Каков наилучший способ перебора строго типизированного универсального 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