C# 遍历强类型泛型 List<T> 的最佳方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15204/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the best way to iterate through a strongly-typed generic List<T>?
提问by billmaya
What is the best way to iterate through a strongly-typed generic List in C#.NET and VB.NET?
在 C#.NET 和 VB.NET 中遍历强类型泛型列表的最佳方法是什么?
采纳答案by mbillard
For C#:
对于 C#:
foreach(ObjectType objectItem in objectTypeList)
{
// ...do some stuff
}
Answer for VB.NET from Purple Ant:
来自Purple Ant 的VB.NET 答案:
For Each objectItem as ObjectType in objectTypeList
'Do some stuff '
Next
回答by Dan Herbert
I may be missing something, but iterating through a generic list should be fairly simple if you use my examples below. The List<> class implements the IList and IEnumerable interfaces so that you can easily iterate through them basically any way you want.
我可能遗漏了一些东西,但是如果您使用下面的示例,遍历通用列表应该相当简单。List<> 类实现了 IList 和 IEnumerable 接口,因此您基本上可以以任何您想要的方式轻松地遍历它们。
The most efficient way would be to use a for loop:
最有效的方法是使用 for 循环:
for(int i = 0; i < genericList.Count; ++i)
{
// Loop body
}
You may also choose to use a foreach loop:
你也可以选择使用 foreach 循环:
foreach(<insertTypeHere> o in genericList)
{
// Loop body
}
回答by Brian G Swanson
For VB.NET:
对于 VB.NET:
For Each tmpObject as ObjectType in ObjectTypeList
'Do some stuff '
Next
回答by Matt Hamilton
Without knowing the internal implementation of a list, I think generally the best way to iterate over it would be a foreach loop. Because foreach uses an IEnumerator to walk over the list, it's up to the list itself to determine how to move from object to object.
在不知道列表的内部实现的情况下,我认为通常迭代它的最佳方法是 foreach 循环。因为 foreach 使用 IEnumerator 遍历列表,所以由列表本身决定如何从一个对象移动到另一个对象。
If the internal implementation was, say, a linked list, then a simple for loop would be quite a bit slower than a foreach.
如果内部实现是一个链表,那么简单的 for 循环会比 foreach 慢很多。
Does that make sense?
那有意义吗?
回答by Keith
With any generic implementation of IEnumerable the best way is:
对于 IEnumerable 的任何通用实现,最好的方法是:
//C#
foreach( var item in listVariable) {
//do stuff
}
There is an important exception however. IEnumerable involves an overhead of Current() and MoveNext() that is what the foreach loop is actually compiled into.
然而,有一个重要的例外。IEnumerable 涉及 Current() 和 MoveNext() 的开销,这就是 foreach 循环实际编译成的内容。
When you have a simple array of structs:
当你有一个简单的结构数组时:
//C#
int[] valueTypeArray;
for(int i=0; i < valueTypeArray.Length; ++i) {
int item = valueTypeArray[i];
//do stuff
}
Is quicker.
比较快。
Update
更新
Following a discussion with @Steven Sudit (see comments) I think my original advice may be out of date or mistaken, so I ran some tests:
在与@Steven Sudit 讨论后(见评论),我认为我最初的建议可能已经过时或错误,所以我进行了一些测试:
// create a list to test with
var theList = Enumerable.Range(0, 100000000).ToList();
// time foreach
var sw = Stopwatch.StartNew();
foreach (var item in theList)
{
int inLoop = item;
}
Console.WriteLine("list foreach: " + sw.Elapsed.ToString());
sw.Reset();
sw.Start();
// time for
int cnt = theList.Count;
for (int i = 0; i < cnt; i++)
{
int inLoop = theList[i];
}
Console.WriteLine("list for : " + sw.Elapsed.ToString());
// now run the same tests, but with an array
var theArray = theList.ToArray();
sw.Reset();
sw.Start();
foreach (var item in theArray)
{
int inLoop = item;
}
Console.WriteLine("array foreach: " + sw.Elapsed.ToString());
sw.Reset();
sw.Start();
// time for
cnt = theArray.Length;
for (int i = 0; i < cnt; i++)
{
int inLoop = theArray[i];
}
Console.WriteLine("array for : " + sw.Elapsed.ToString());
Console.ReadKey();
So, I ran this in release with all optimisations:
所以,我在所有优化的发行版中运行了这个:
list foreach: 00:00:00.5137506
list for : 00:00:00.2417709
array foreach: 00:00:00.1085653
array for : 00:00:00.0954890
And then debug without optimisations:
然后在没有优化的情况下进行调试:
list foreach: 00:00:01.1289015
list for : 00:00:00.9945345
array foreach: 00:00:00.6405422
array for : 00:00:00.4913245
So it appears fairly consistent, for
is quicker than foreach
and arrays are quicker than generic lists.
所以它看起来相当一致,比通用列表for
更快foreach
,数组也比通用列表更快。
However, this is across 100,000,000 iterations and the difference is about .4 of a second between the fastest and slowest methods. Unless you're doing massive performance critical loops it just isn't worth worrying about.
然而,这是跨越 100,000,000 次迭代,最快和最慢方法之间的差异约为 0.4 秒。除非您正在执行大量性能关键循环,否则不值得担心。
回答by Adam Lassek
C#
C#
myList<string>().ForEach(
delegate(string name)
{
Console.WriteLine(name);
});
Anonymous delegates are not currently implemented in VB.Net, but both C# and VB.Net should be able to do lambdas:
匿名委托目前未在 VB.Net 中实现,但 C# 和 VB.Net 都应该能够执行 lambdas:
C#
C#
myList<string>().ForEach(name => Console.WriteLine(name));
VB.Net
VB.Net
myList(Of String)().ForEach(Function(name) Console.WriteLine(name))
As Grauenwolf pointed out the above VB won't compile since the lambda doesn't return a value. A normal ForEach loop as others have suggested is probably the easiest for now, but as usual it takes a block of code to do what C# can do in one line.
正如 Grauenwolf 指出的那样,上面的 VB 不会编译,因为 lambda 不返回值。正如其他人所建议的那样,一个普通的 ForEach 循环现在可能是最简单的,但像往常一样,它需要一段代码来完成 C# 可以在一行中完成的工作。
Here's a trite example of why this might be useful: this gives you the ability to pass in the loop logic from another scope than where the IEnumerable exists, so you don't even have to expose it if you don't want to.
这是一个说明为什么这可能有用的陈腐示例:这使您能够从 IEnumerable 所在的其他范围传入循环逻辑,因此如果您不想,您甚至不必公开它。
Say you have a list of relative url paths that you want to make absolute:
假设您有一个要设为绝对的相对 url 路径列表:
public IEnumerable<String> Paths(Func<String> formatter) {
List<String> paths = new List<String>()
{
"/about", "/contact", "/services"
};
return paths.ForEach(formatter);
}
So then you could call the function this way:
那么你可以这样调用函数:
var hostname = "myhost.com";
var formatter = f => String.Format("http://{0}{1}", hostname, f);
IEnumerable<String> absolutePaths = Paths(formatter);
Giving you "http://myhost.com/about", "http://myhost.com/contact"
etc. Obviously there are better ways to accomplish this in this specfic example, I'm just trying to demonstrate the basic principle.
给你"http://myhost.com/about", "http://myhost.com/contact"
等等。显然在这个特定的例子中有更好的方法来实现这一点,我只是想演示基本原理。
回答by jfs
It depends on your application:
这取决于您的应用程序:
- for loop, if efficiency is a priority
- foreach loop or ForEach method, whichever communicates your intent more clearly
- for 循环,如果效率是优先考虑的
- foreach 循环或 ForEach 方法,以更清楚地传达您的意图为准