我有这个类,但我不明白为什么有一个实现是有用的: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;
}
}
我试图理解两种实现之间的区别,但我做不到。
当您想以某种方式限制使用时,显式接口实现会很有用。或者,如果您希望实现以某种方式有所不同,但您可能希望限制任何差异,因为它可能会使代码更难以推理。
在您的具体示例中,提供隐式和显式接口实现是没有意义的,因为它们之间没有真正的区别。但请考虑以下示例:
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 和接口完全没有重叠。由于创建进度对象需要注册事件处理程序等,但不需要报告进度,并且使用该接口的方法应该仅报告进度。
你当然可以通过类型检查来回避这种“保护”,但是如果你发现自己这样做,你可能应该多想一下你是否在做正确的事情。