通过强类型泛型List <T>进行迭代的最佳方法是什么?
在C#.NET和VB.NET中通过强类型泛型列表进行迭代的最佳方法是什么?
解决方案
回答
对于C#:
foreach(ObjectType objectItem in objectTypeList) { // ...do some stuff }
紫色蚂蚁为VB.NET的答案:
For Each objectItem as ObjectType in objectTypeList 'Do some stuff ' Next
回答
我可能会丢失一些内容,但是如果我们使用下面的示例,遍历通用列表应该非常简单。 List <>类实现了IList和IEnumerable接口,因此我们可以轻松地基本上以任何所需的方式遍历它们。
最有效的方法是使用for循环:
for(int i = 0; i < genericList.Count; ++i) { // Loop body }
我们也可以选择使用foreach循环:
foreach(<insertTypeHere> o in genericList) { // Loop body }
回答
对于VB.NET:
当我们有一个简单的结构数组时:
For Each tmpObject as ObjectType in ObjectTypeList 'Do some stuff ' Next Answer 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. If the internal implementation was, say, a linked list, then a simple for loop would be quite a bit slower than a foreach. Does that make sense? Answer With any generic implementation of IEnumerable the best way is: //C# foreach( var item in listVariable) { //do stuff }
更快。
更新
经过与@Steven Sudit的讨论(请参阅评论),我认为我最初的建议可能已过时或者错误,因此我进行了一些测试:
//C# int[] valueTypeArray; for(int i=0; i < valueTypeArray.Length; ++i) { int item = valueTypeArray[i]; //do stuff }
因此,我在发布时进行了所有优化:
// 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();
然后在没有优化的情况下进行调试:
list foreach: 00:00:00.5137506 list for : 00:00:00.2417709 array foreach: 00:00:00.1085653 array for : 00:00:00.0954890
因此看起来相当一致,for的速度比foreach的速度快,数组的速度比泛型列表的速度快。
但是,这跨越了100,000,000次迭代,最快和最慢的方法之间的差异约为0.4秒。除非我们要执行大量的性能关键循环,否则就不必担心。
回答
C#
list foreach: 00:00:01.1289015 list for : 00:00:00.9945345 array foreach: 00:00:00.6405422 array for : 00:00:00.4913245
VB.Net当前未实现匿名委托,但是Cand VB.Net都应能够执行lambda:
C#
myList<string>().ForEach( delegate(string name) { Console.WriteLine(name); });
VB.Net
myList<string>().ForEach(name => Console.WriteLine(name));
正如Grauenwolf指出的那样,由于lambda不返回值,因此上述VB无法编译。正如其他人所建议的那样,正常的ForEach循环目前可能是最简单的,但是像往常一样,它需要一段代码来完成Ccan在一行中执行的操作。
这是一个为什么可能有用的简单例子:这使我们能够从IEnumerable所在的另一个作用域传递循环逻辑,因此,即使我们不想公开它,也不必公开它。
假设我们有一个要设为绝对的相对URL路径列表:
myList(Of String)().ForEach(Function(name) Console.WriteLine(name))
因此,我们可以通过以下方式调用该函数:
public IEnumerable<String> Paths(Func<String> formatter) { List<String> paths = new List<String>() { "/about", "/contact", "/services" }; return paths.ForEach(formatter); }
为我们提供" http://myhost.com/about"、"http://myhost.com/contact"等。显然,在此特定示例中,有更好的方法可以实现此目的,我只是在尝试演示基本原则。
回答
这取决于应用程序:
- for循环,如果效率是重中之重
- foreach循环或者ForEach方法,以更清晰的方式传达意图
代码数量不匹配