26

很长一段时间以来,我对以下内容感到好奇:

int[] array = new int[1];
int iArrayLength = array.Length;    //1

由于数组实现了 IList 接口,因此允许以下操作:

int iArrayCount = ((IList<int>)array).Count;    //still 1

但:

int iArrayCount = array.Count;  //Compile error. WHY?
int iArrayLength = array.Length;    //This is what we learned at school!

问题:数组如何实现IList<T>(尤其是int Count { get; }from 的属性IList<T>)而不允许在基类上使用它?

4

2 回答 2

32

这称为显式接口成员实现。接口成员不作为类型的公共成员公开,但可以通过将引用转换为接口类型来使用。

这可以像这样在 C# 中完成:

interface I
{
    void M();
}

class C : I
{
    public int P { get; set; }
    void I.M() { Console.WriteLine("M!"); }
}

然后你可以像这样使用这些类型:

C obj = new C();
obj.P = 3;
((I)obj).M();

但这不会编译:

obj.M();

正如 JeffN825 所指出的,显式实现接口成员的一个原因是类型不支持它们。例如,Add抛出异常(相关讨论)。显式实现成员的另一个原因是它复制了另一个具有不同名称的公共成员。这Count就是明确实施的原因;对应的public成员是Length. 最后隐式实现的一些成员,即indexer。这两行都有效(假设arr是一个数组int):

arr[0] = 8;
((IList<int>)arr)[0] = 8;
于 2012-09-17T14:24:27.480 回答
13

因为 Array 不支持 IList 的所有功能(添加/删除/等),所以 IList.Count(和其他几种方法)都是私有(显式)实现的。你可以在反汇编中看到:

int ICollection.Count

如果你真的想使用 Count,你可以这样做

((IList)myArray).Count
于 2012-09-17T14:24:08.087 回答