为什么我不能明确设置 GetEnumerator 的访问级别?

问题描述

我正在创建一个实现 ICollection<T> 的简单集合,根据我的理解,它继承自 IEnumerable<T>当时它被称为接口继承,对吗?) .使用实现的自动生成代码,有一个 GetEnumerator 方法使用的语法让我有点困惑:

IEnumerator IEnumerable.GetEnumerator() { ... }

我最初认为这是一个 private 方法,因为所有其他自动生成的块都指定为 public,我正在尝试对实现代码进行分类和清理。因此,出于习惯,我尝试始终明确使用我的访问修饰符,并尝试使用所有访问级别标记方法。然而,这导致了一个错误,本质上很简单:

修饰符 x 对此项无效。

这让我怀疑到底发生了什么,但我的网络搜索却没有任何结果。


为什么我不能为这个方法显式设置访问级别?

解决方法

通常在实现接口时,必须为方法和属性指定 public。在这种情况下,这些方法和属性不仅有助于实现接口,而且就像任何其他常规方法或属性一样。能够向它们添加 public 是有道理的。但是,您在此处声明的 IEnumerator.GetEnumerator 有点特殊。

这是 explicit interface implementationIEnumerable.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 通常的含义有些不同? 老实说,没有一个访问修饰符可以真正表达显式接口实现的可访问性