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

Why can't I explicitly set the access level for GetEnumerator?

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

IEnumerator IEnumerable.GetEnumerator() { ... }

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

The modifier x is not valid for this item.

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


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

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

这是一个 explicit interface implementation of IEnumerable.GetEnumerator. Just in case you didn't know, this is the non-generic (by which I mean, returns a non-generic IEnumerator) version of IEnumerable<T>.GetEnumerator,在 IEnumerable 中声明(不要与 IEnumerable<T> 混淆!)。由于IEnumerable<T>继承自IEnumerable,因此在实现IEnumerable<T>.

时需要同时实现两者

如果您在这里没有使用显式接口实现,您将有两个同名的方法,它们都不接受任何参数,只有 return 值不同:

public IEnumerator<int> GetEnumerator()
{
    ...
}

public IEnumerator GetEnumerator() // CS0111
{
    ...
}

这是不允许的。这就是显式接口实现的用武之地。如果您通过在其来源的接口名称前加上前缀来声明 non-generic GetEnumerator

IEnumerator IEnumerable.GetEnumerator()
{
    ...
}

那么这个方法只能在类型为 IEnumerable的表达式上访问。例如,假设您的 collection 被称为 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()

即使在同一个 class 中,如果不首先转换为 IEnumerable,您也无法访问 non-generic GetEnumerator。你看出这与 private 通常的意思有何不同吗? None 的访问修饰符确实可以表达显式接口实现的可访问性,老实说。