0

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

IEnumerator IEnumerable.GetEnumerator() { ... }

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

修饰符x对此项无效。

这让我质疑到底发生了什么,但我的网络搜索并没有出现任何问题。


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

4

1 回答 1

1

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

这是一个显式的接口实现IEnumerable.GetEnumerator以防万一你不知道,这是非泛型(我的意思是,返回非泛型IEnumerator)版本IEnumerable<T>.GetEnumerator,声明在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通常的含义有何不同吗?老实说,没有一个访问修饰符可以真正表达显式接口实现的可访问性。

于 2021-06-26T01:46:08.787 回答