在一个数组中计算元素的数量

3

System.Array类实现ICollection接口。这个接口有一个名为Count的公共属性,用于获取数组中元素的数量。

假设我声明了一个数组并访问它的属性:

Array numbers = Array.CreateInstance(typeof(int), 10);
Console.WriteLine(numbers.Count);

您会期望屏幕上看到10。 但是,在数字后面添加句点后,我无法看到Count属性。 然而,有一个名为Length的属性。这是为什么呢?
更新: 这是因为显式接口实现。 由于有另一个类似于我的问题,我决定重新表述一下。 为什么要采取设计决策来明确实现特定属性?已经有一个具有相同功能的属性Length。那么为什么要费力地提供明确实现的Count

将其转换为 ICollection - Tim Schmelter
为什么您不使用int[] number = new int[10];呢? - PhonicUK
@PhonicUK,我正在使用的方法也是声明“数组”的有效方式。您提到的语法有什么优势吗? - TheSilverBullet
1
@TheSilverBullet 使用Array.CreateInstance是可以的,但不应使用Array类型来处理数组。如果您尝试访问此数组的元素,您将得到object而不是int32。这将导致装箱http://msdn.microsoft.com/en-us/library/yz2be5wk(v=vs.80).aspx。装箱是不好的。 - Dmitrii Dovgopolyi
4个回答

4
你需要将它转换为ICollectionArray.ICollection.Count属性
这个成员是一个显式接口成员实现。只有当Array实例转换为ICollection接口时才能使用它。
顺便说一句,这里有一个重复的问题: I can not access Count property of the array but through casting to ICollection ! 更新:
这是因为显式接口实现。由于还有一个类似于我的问题,我决定重新表述一下。为什么要采取设计决策来明确实现这个特定的属性?还有另一个具有相同功能的属性Length。那么为什么要费心提供明确实现的Count呢?
它继承自实现了ICollection<T>IList<T>。所以你可以问的是为什么数组实现了IList

据我所知,Array并不是从List<T>继承而来的。我是否漏掉了什么?感谢提供链接,从讨论中学到了有价值的东西。 - TheSilverBullet
1
@TheSilverBullet:在 C# 2.0 及其后续版本中,下限为零的单维数组自动实现了 IList<T> 接口。http://msdn.microsoft.com/zh-cn/library/ms228502(v=vs.110).aspx - Tim Schmelter
你提供的链接非常有帮助,它让我重新阅读了一些关于列表接口设计的部分。我还想问一下为什么决定自动实现IList<T>接口。但是现在我更愿意把这个问题留到另一天再讨论。我希望我也能接受你的问题... - TheSilverBullet

2

System.Array类显式实现了ICollection接口。您只能在将Array强制转换为ICollection之后使用ICollection的方法。

Array numbers = Array.CreateInstance(typeof(int), 10);
ICollection numbersCollection =  (ICollection)numbers;
Console.WriteLine(numbersCollection.Count);

隐式和显式接口实现

System.Array.Count 实际上使用的是 Array.Length 属性

int ICollection.Count
{
    get
    {
        return this.Length;
    }
}

所以,你基本上是说区别只在于所使用的词汇。这样做是为了方便理解。本质上是一种方便之举。 - TheSilverBullet
我不知道为什么要这样做。 - Dmitrii Dovgopolyi
Ken Kin在下面给出了一个非常可接受的解释。感谢您的回答!我已经接受了你的回答。 - TheSilverBullet

1
我认为这不是一个编程问题,而是逻辑intension的问题。
你可以问自己这两个问题:
Q1. 数组是集合吗?
Q2. 集合是数组吗?
在c#中,现有的实现表明Q1的答案是:
A1:是的,数组是集合。因此,Array 实现了 ICollection
那么Q2呢?这类似于问一匹马是白色的马吗?您可能需要查看[当一匹白马不是一匹马时]以获取答案。
我会翻译成中文:
使用Q2,我的回答是:“我不知道,这要看上下文。” 那么,可能的上下文是什么?如果您将一个数组作为接口实现传递给ICollection,那么是的,这个集合也是一个数组。但是,除了具有相同接口的数组之外,您可能会传递一个不同的对象。那么,它是否一定是一个数组?如果您对此有兴趣,可以参考[this answer]中的A3来获取想法。
因此,Array拥有Length属性和从ICollection的显式实现中得到的Count属性,这是完全合理的。

这个答案在完全不同的方面比其他答案有所帮助。我质疑意图的原因仅仅是因为我想挖掘一些真实的设计决策,并了解为什么要这样做。 - TheSilverBullet

1

Count 属性是从 ICollection 接口显式实现的,因此它是不可见的。要访问 Count 属性,您需要将 ((ICollection) numbers).Count 进行强制类型转换。


1
谢谢,yBee。问题是一旦你使用语法来转换数组变量,就不会提示任何属性。我不得不手动输入“Count”,然后它就可以工作了。你认为这是为什么? - TheSilverBullet
1
@TheSilverBullet:为什么Count是明确的呢?为什么不用Length呢?程序员习惯于在谈论数组时使用Length。但另一方面,对于IEnumerable有一个名为Count()的扩展方法,实际上在操作数组时会返回Length。所以你可能应该在这里使用IEnumerable.Count()而不是强制转换为ICollection - Ryszard Dżegan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接