IEnumerable 的 GetEnumerator() 隐式和显式实现之间的区别

问题描述 投票:0回答:1

我有这个类,但我不明白为什么有一个实现是有用的:public IEnumerator GetEnumerator(),另一个实现是:IEnumerator IEnumerable.GetEnumerator()。我知道要使用第二个,我必须将其作为接口本身的实例而不是类的实例来访问,因为该成员不可见,但我无法理解这些技术的区别和有用性。

internal class CoffeeCollection : IEnumerable
{

    private CoffeeEnumerator enumerator;

    public CoffeeCollection()
    {
        enumerator = new CoffeeEnumerator();
    }

    public IEnumerator GetEnumerator()
    {
        return enumerator;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        Form1.labelExplicitImplementation.Visible = true;
        return enumerator;
    }
}

我试图理解两种实现之间的区别,但我做不到。

c# interface ienumerable implementation ienumerator
1个回答
0
投票

当您想以某种方式限制使用时,显式接口实现会很有用。或者,如果您希望实现以某种方式有所不同,但您可能希望限制任何差异,因为它可能会使代码更难以推理。

在您的具体示例中,提供隐式和显式接口实现是没有意义的,因为它们之间没有真正的区别。但请考虑以下示例:

public interface IMyObject{}
public class MyObject : IMyObject{}

public interface IMyService
{
    IMyObject Object { get; }
}
public class MyService : IMyService
{
    public MyObject Object { get; set; } = new MyObject();
    IMyObject IMyService.Object  => this.Object;
}

如果您有

IMyService
引用,您只能获取对象的接口。但是,如果您有
MyService
引用,您就可以访问基础类型,并且还可以更改对象。因此,这可以让您根据组件的需要在组件之间获得一定程度的分离和隔离。

一个现实世界的例子是实现 Progress<T>

IProgress<T>
 类。其中基类的 API 和接口完全没有重叠。由于创建进度对象需要注册事件处理程序等,但不需要报告进度,并且使用该接口的方法应该报告进度。

你当然可以通过类型检查来回避这种“保护”,但是如果你发现自己这样做,你可能应该多想一下你是否在做正确的事情。

© www.soinside.com 2019 - 2024. All rights reserved.