问题描述
我正在创建一个实现 ICollection<T>
的简单集合,根据我的理解,它继承自 IEnumerable<T>
(当时它被称为接口继承,对吗?) .使用实现的自动生成代码,有一个 GetEnumerator
方法使用的语法让我有点困惑:
IEnumerator IEnumerable.GetEnumerator() { ... }
我最初认为这是一个 private
方法,因为所有其他自动生成的块都指定为 public,我正在尝试对实现代码进行分类和清理。因此,出于习惯,我尝试始终明确使用我的访问修饰符,并尝试使用所有访问级别标记该方法。然而,这导致了一个错误,本质上很简单:
修饰符 x
对此项无效。
这让我怀疑到底发生了什么,但我的网络搜索却没有任何结果。
为什么我不能为这个方法显式设置访问级别?
解决方法
通常在实现接口时,必须为方法和属性指定 public
。在这种情况下,这些方法和属性不仅有助于实现接口,而且就像任何其他常规方法或属性一样。能够向它们添加 public
是有道理的。但是,您在此处声明的 IEnumerator.GetEnumerator
有点特殊。
这是 explicit interface implementation 的 IEnumerable.GetEnumerator
。以防万一您不知道,这是 IEnumerable<T>.GetEnumerator
的非泛型(我的意思是返回非泛型 IEnumerator
)版本,在 IEnumerable
中声明(不是与 IEnumerable<T>
混淆!)。由于 IEnumerable<T>
继承自 IEnumerable
,因此您在实现 IEnumerable<T>
时需要同时实现。
如果这里没有使用显式接口实现,您将有两个同名的方法,都不接受任何参数,只有返回值不同:
public IEnumerator<int> GetEnumerator()
{
...
}
public IEnumerator GetEnumerator() // CS0111
{
...
}
这是不允许的。这就是显式接口实现的用武之地。如果您通过在其来源接口的名称前加上前缀来声明非泛型 GetEnumerator
:
IEnumerator IEnumerable.GetEnumerator()
{
...
}
那么此方法只能在类型为 IEnumerable
的表达式上访问。例如,假设您的集合名为 MyCollection
。
MyCollection myCollection = ...;
// this accesses the *generic* GetEnumerator,the non-generic one is not accessible
myCollection.GetEnumerator()
// the non generic one is only accessible if you cast to IEnumerable
((IEnumerable)myCollection).GetEnumerator()
即使在同一个类中,如果不先强制转换为 GetEnumerator
,您也无法访问非泛型 IEnumerable
。您是否看到这与 private
通常的含义有些不同? 老实说,没有一个访问修饰符可以真正表达显式接口实现的可访问性。