Вероятно, вам следует учитывать и LINQ, если вы ориентируетесь на C # в качестве языка, поскольку это еще один логический способ создания циклов.
С помощью выполните операцию для каждого элемента в списке Вы имеете в виду изменить его на месте в списке или просто сделать что-то с элементом (например, распечатать его, накопить, изменить его и т. д.)?Я подозреваю, что это последнее, так как foreach
в C # не позволит вам изменить коллекцию, которую вы зацикливаете, или, по крайней мере, не удобным способом ...
Вот две простые конструкции,сначала с помощью for
, а затем с помощью foreach
, который посещает все строки в списке и превращает их в строки в верхнем регистре:
List<string> list = ...;
List<string> uppercase = new List<string> ();
for (int i = 0; i < list.Count; i++)
{
string name = list[i];
uppercase.Add (name.ToUpper ());
}
(обратите внимание, что используется конечное условие i < list.Count
вместо i < length
с некоторым прекомпьютером length
константа считается хорошей практикой в .NET, так как в любом случае компилятору придется проверять верхнюю границу, когда list[i]
вызывается в цикле; если мое понимание верно, компилятор может в некоторых случаяхобстоятельства, позволяющие оптимизировать проверку верхней границы, которую она обычно выполняла бы).
Вот эквивалент foreach
:
List<string> list = ...;
List<string> uppercase = new List<string> ();
foreach (name in list)
{
uppercase.Add (name.ToUpper ());
}
Примечание: в основном, конструкция foreach
может повторятьсялюбые IEnumerable
или IEnumerable<T>
в C #, а не только над массивами или списками.Поэтому количество элементов в коллекции может быть неизвестно заранее или даже может быть бесконечным (в этом случае вам, безусловно, придется включить в цикл какое-то условие завершения, иначе оно не выйдет).
Вот несколько эквивалентных решений, которые я могу придумать, выраженных с использованием C # LINQ (и которые вводят концепцию лямбда-выражения , в основном встроенную функцию, принимающую x
и возвращающую x.ToUpper ()
в следующих примерах):
List<string> list = ...;
List<string> uppercase = new List<string> ();
uppercase.AddRange (list.Select (x => x.ToUpper ()));
Или со списком uppercase
, заполненным его конструктором:
List<string> list = ...;
List<string> uppercase = new List<string> (list.Select (x => x.ToUpper ()));
Или то же самое с использованием функции ToList
:
List<string> list = ...;
List<string> uppercase = list.Select (x => x.ToUpper ()).ToList ();
Или то же самое с выводом типа:
List<string> list = ...;
var uppercase = list.Select (x => x.ToUpper ()).ToList ();
или если вы не возражаете получить результат как IEnumerable<string>
(перечисляемая коллекция строк), вы можете удалить ToList
:
List<string> list = ...;
var uppercase = list.Select (x => x.ToUpper ());
Или, может быть, еще один с C # SQL-подобными ключевыми словами from
и select
, что полностью эквивалентно:
List<string> list = ...;
var uppercase = from name in list
select name => name.ToUpper ();
LINQ очень выразителен и очень часто, ячувствую, что код моудобнее для чтения, чем простой цикл.
Ваш второй вопрос, поиск элемента в списке, и желание выйти, когда этот элемент найден также может быть очень удобно реализовано с помощью LINQ.Вот пример цикла foreach
:
List<string> list = ...;
string result = null;
foreach (name in list)
{
if (name.Contains ("Pierre"))
{
result = name;
break;
}
}
Вот простой эквивалент LINQ:
List<string> list = ...;
string result = list.Where (x => x.Contains ("Pierre")).FirstOrDefault ();
или с синтаксисом запроса:
List<string> list = ...;
var results = from name in list
where name.Contains ("Pierre")
select name;
string result = results.FirstOrDefault ();
Перечисление results
выполняется только по требованию , что означает, что фактически список будет повторяться только до тех пор, пока не будет выполнено условие, при вызове для него метода FirstOrDefault
.
Я надеюсь, что это принесет больше контекста в дебаты for
или foreach
, по крайней мере, в мире .NET.