我正在逐步查看大量的对象,以便对列表中的所述对象进行一些操作。
在我的迭代过程中,我会根据某些标准从列表中删除一些对象。
完成所有操作后,我需要更新有关列表中对象数量的UI。 (T列表)。
问题:
当我调用list.count时,.net实际上遍历列表 计算它,还是将计数存储为属性/变量?
如果.net在列表中进行物理重新迭代,我也可以通过列表在我自己的迭代中保留一个计数器,并节省开销?
由于
答案 0 :(得分:18)
它只是保留一个内部int来跟踪项目数。所以没有迭代。 文档说检索Count是一个O(1)操作:
http://msdn.microsoft.com/en-us/library/27b47ht3%28v=vs.110%29.aspx
你可以亲眼看看:
http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs
答案 1 :(得分:7)
List
作为数组列表实现,它跟踪自己的大小,因此调用.Count
属性不需要任何迭代。
如果你调用LINQ .Count()
扩展方法,这将检查基础IEnumerable<>
是否实现ICollection
(List<>
做了什么),并使用{{1如果可能,该接口上的属性。所以这不会导致任何迭代发生。
顺便提一下,如果您在迭代中尝试从列表中删除项目时,还会遇到其他问题。当你从迭代器中删除元素时,迭代应该如何表现并不是很清楚,所以.Count
s将完全避免这个问题,如果列表自创建枚举器以来已被修改则抛出异常
答案 2 :(得分:3)
您可以使用反编译器(例如可自由使用的ILSpy)来回答这些问题。如果您引用的是List<T>
类型,则Count
获取者只需阅读字段:
public int Count
{
get { return this._size; }
}
答案 3 :(得分:1)
如备注标签下所述 http://msdn.microsoft.com/en-us/library/27b47ht3(v=vs.110).aspx
检索此属性的值是O(1)操作。
这意味着没有发生迭代。
答案 4 :(得分:1)
您使用vb.net和c#标记了您的问题,因此在回复&#34;如果.net物理地重新遍历列表,我也可以在我自己的迭代中通过列表保留一个计数器,并节省开销?&#34;
如果您的迭代使用For i = first To last
,则VB.NET会在进入循环时评估first
和last
:
Dim first As Integer = 1
Dim last As Integer = 3
For i = first To last
Console.Write(i.ToString() & " ")
last = -99
Next
输出:1 2 3
如果您在C#中执行等效操作,则会在每次迭代时评估first
和last
:
int first = 1;
int last = 1;
for (int i = first; i <= last; i++)
{
Console.Write(i.ToString() + " ");
last = -99;
}
输出:1
如果您的.Count()函数/属性评估成本高昂且/或者您不希望在每次迭代时重新评估它(出于其他原因),那么在C#中您可以将其分配给一个临时变量。