Каков наилучший способ перебора строго типизированного универсального List<T>?

Как лучше всего выполнить итерацию по строго 9X_c-sharp типизированному общему списку в C#.NET и 9X_c#.net VB.NET?

17
0
7
Общее количество ответов: 7

Ответ #1

Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?

Для С#:

foreach(ObjectType objectItem in objectTypeList) { // ...do some stuff } 

Ответ для VB.NET от Purple Ant:

For Each objectItem as ObjectType in objectTypeList 'Do some stuff ' Next 

9X_.net-framework

32
1

  • Поскольку он строго типизирован, вы также можете использовать: `foreach (var i ...

Ответ #2

Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?

С любой универсальной реализацией IEnumerable 9X_java-generics лучший способ:

//C# foreach( var item in listVariable) { //do stuff } 

Однако есть важное исключение. IEnumerable 9X_c-sharp включает накладные расходы на Current() и 9X_collection MoveNext(), то есть то, во что фактически 9X_vbproj скомпилирован цикл foreach.

Если у вас есть 9X_generics простой массив структур:

//C# int[] valueTypeArray; for(int i=0; i < valueTypeArray.Length; ++i) { int item = valueTypeArray[i]; //do stuff } 

Быстрее.


Обновление

После обсуждения 9X_c#.net с @Steven Sudit (см. комментарии) я думаю, что 9X_vbproj мой первоначальный совет может быть устаревшим 9X_generic или ошибочным, поэтому я провел несколько 9X_c-sharp тестов:

// 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(); 

Итак, я запустил это в релизе со 9X_c-sharp всеми оптимизациями:

list foreach: 00:00:00.5137506 list for : 00:00:00.2417709 array foreach: 00:00:00.1085653 array for : 00:00:00.0954890 

А потом отлаживать без 9X_collections оптимизаций:

list foreach: 00:00:01.1289015 list for : 00:00:00.9945345 array foreach: 00:00:00.6405422 array for : 00:00:00.4913245 

Таким образом, это кажется довольно 9X_java-generics последовательным, for быстрее, чем foreach, а массивы 9X_c-sharp быстрее, чем общие списки.

Однако это происходит 9X_dot-net через 100 000 000 итераций, и разница составляет 9X_generic около 0,4 секунды между самым быстрым и 9X_java-collections-api самым медленным методами. Если вы не выполняете 9X_c#.net массивные критические циклы производительности, об 9X_generics этом просто не стоит беспокоиться.

21
1

  • Позвольте мне поблагодарить вас за тяжелую работу, но я должен упомянуть, что у моих тестов было одно ключевое отличие: я ...

Ответ #3

Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?

С#

myList().ForEach( delegate(string name) { Console.WriteLine(name); }); 

Анонимные делегаты в настоящее время не 9X_.net-framework реализованы в VB.Net, но и C#, и VB.Net 9X_.net должны уметь выполнять лямбда-выражения:

С#

myList().ForEach(name => Console.WriteLine(name)); 

ВБ.Нет

myList(Of String)().ForEach(Function(name) Console.WriteLine(name)) 

Как 9X_.net заметил Грауэнвольф, приведенный выше VB 9X_vb.net не будет компилироваться, поскольку лямбда 9X_c-sharp не возвращает значение. Обычный цикл ForEach, как 9X_vbproj предлагали другие, на данный момент, вероятно, самый 9X_c#.net простой, но, как обычно, требуется блок 9X_.net кода, чтобы сделать то, что С# может сделать 9X_c-sharp в одной строке.


Вот банальный пример того, почему 9X_.net-framework это может быть полезно: это дает вам возможность 9X_dotnet передавать логику цикла из другой области, отличной 9X_vb.net от той, где существует IEnumerable, поэтому 9X_c# вам даже не нужно выставлять ее, если вы 9X_dotnet этого не хотите.

Допустим, у вас есть список 9X_csharp относительных URL-адресов, которые вы хотите 9X_vbproj сделать абсолютными:

public IEnumerable Paths(Func formatter) { List paths = new List() { "/about", "/contact", "/services" }; return paths.ForEach(formatter); } 

Тогда вы могли бы вызвать 9X_dot-net функцию следующим образом:

var hostname = "myhost.com"; var formatter = f => String.Format("http://{0}{1}", hostname, f); IEnumerable absolutePaths = Paths(formatter); 

Предоставление 9X_vbproj вам "http://myhost.com/about", "http://myhost.com/contact" и т. д. Очевидно, что есть лучшие способы 9X_java-collections-api сделать это в этом конкретном примере, я 9X_generic просто пытаюсь продемонстрировать основной 9X_generics принцип.

5
0

Ответ #4

Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?

Для VB.NET:

For Each tmpObject as ObjectType in ObjectTypeList 'Do some stuff ' Next

9X_csharp

4
0

Ответ #5

Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?

Не зная внутренней реализации списка, я 9X_vb думаю, что лучшим способом перебора списка 9X_vb будет цикл foreach. Поскольку foreach использует 9X_c#.net IEnumerator для обхода списка, сам список 9X_c#.net определяет, как переходить от объекта к 9X_collections объекту.

Если бы внутренней реализацией был, скажем, связанный 9X_c# список, то простой цикл for был бы немного 9X_collection медленнее, чем foreach.

Имеет ли это смысл?

2
0

Ответ #6

Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?

Это зависит от вашего приложения:

  • цикл for, если эффективность является приоритетом
  • цикл foreach или метод ForEach, в зависимости от того, что более четко передает ваши намерения

9X_vbproj

2
0

Ответ #7

Ответ на вопрос: Каков наилучший способ перебора строго типизированного универсального List<T>?

Я могу что-то упустить, но повторение общего 9X_collection списка должно быть довольно простым, если 9X_.net вы используете мои примеры ниже. Класс List<> реализует 9X_dot-net интерфейсы IList и IEnumerable, так что 9X_collections вы можете легко перебирать их практически 9X_dotnet любым удобным для вас способом.

Наиболее 9X_generics эффективным способом было бы использование 9X_dotnet цикла for:

for(int i = 0; i < genericList.Count; ++i) { // Loop body } 

Вы также можете использовать цикл 9X_generic foreach:

foreach( o in genericList) { // Loop body } 

1
0