Вы можете выбрать другой принятый ответ, поскольку тот, который вы выбрали, на самом деле не соответствует правильному ответу.
Джордж Стокер,
Ответы:
162
На самом деле, строго говоря, все, что вам нужно использовать, foreach- это общедоступный GetEnumerator()метод, который возвращает что-то вместе с bool MoveNext()методом и ? Current {get;}свойством. Однако наиболее распространенное значение этого слова - «что-то, что реализует IEnumerable/ IEnumerable<T>, возвращая IEnumerator/ IEnumerator<T>.
Косвенно, это включает в себя все , что инвентарь ICollection/ ICollection<T>, например, что - нибудь подобное Collection<T>, List<T>массивы ( T[]) и т.д. Таким образом , любой стандартный «сбор данных», как правило , поддерживают foreach.
Для доказательства первого пункта отлично работает следующее:
using System;
classFoo {
publicint Current { get; privateset; }
privateint step;
publicboolMoveNext() {
if (step >= 5) returnfalse;
Current = step++;
returntrue;
}
}
classBar {
public Foo GetEnumerator() { returnnew Foo(); }
}
staticclassProgram {
staticvoidMain() {
Bar bar = new Bar();
foreach (int item in bar) {
Console.WriteLine(item);
}
}
}
Как это работает?
Цикл foreach вроде foreach(int i in obj) {...}kinda означает:
var tmp = obj.GetEnumerator();
int i; // up to C# 4.0while(tmp.MoveNext()) {
int i; // C# 5.0
i = tmp.Current;
{...} // your code
}
Однако есть и вариации. Например, если перечислитель (tmp) поддерживает IDisposable, он тоже используется (аналогично using).
Обратите внимание на разницу в размещении объявления " int i" внутри (C # 5.0) и вне (до C # 4.0) цикла. Это важно, если вы используете iанонимный метод / лямбду внутри своего блока кода. Но это уже другая история ;-p
+1 за углубление. Обычно я не углубляюсь в вопрос, который может быть вопросом «новичка», так как он покажется непосильным для нового программиста.
Джордж Стокер,
Верно, Горток - поэтому я продолжил работу со списками / массивами и т. Д.
Марк Гравелл
Было бы хорошо упомянуть неявное приведение во время выполнения к переменной цикла - это может привести к исключениям несовместимости типов.
Дэниел Эрвикер,
3
Не забывайте: при использовании массива с foreach компилятор создает простой for-loop(вы можете увидеть это при работе с IL).
Феликс К.
1
@Marc Gravell: Хорошо, круто! Я отредактировал сообщение, чтобы было понятнее - по крайней мере, для меня. В конце концов, размещение важно не только в C # 5.0, оно всегда важно, только то, что оно изменилось. Надеюсь, ты не против.
foreachУтверждение повторяет группу вложенных заявлений для каждого элемента в массиве или коллекции объектов . Вforeach используется для итерации по коллекции для получения желаемой информации, но не должен использоваться для изменения содержимого коллекции, чтобы избежать непредсказуемых побочных эффектов. (курсив мой)
Итак, если у вас есть массив, вы можете использовать оператор foreach для итерации по массиву, например:
как ни странно, согласно MSDN ( msdn.microsoft.com/en-us/library/9yb8xew9(VS.80).aspx ), типы объектов не нуждаются в реализации IEnumerable. Подойдет любой тип, который правильно определяет GetEnumerator, MoveNext, Reset и Current. Странно, да?
Шон Рейли,
Аккуратно. Я этого не знал. :-)
Джордж Стокер
4
Согласно сообщению в блоге Duck Notation , используется утиная печать.
Важно отметить, что «Тип элемента коллекции должен быть преобразован в тип идентификатора». Иногда это невозможно проверить во время компиляции и может вызвать исключение времени выполнения, если тип экземпляра не может быть назначен ссылочному типу.
Это вызовет исключение времени выполнения, если в корзине с фруктами есть не Apple, например апельсин.
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)
Это безопасно фильтрует список только для яблок с помощью Enumerable.OfType
List<int> numbers = new List<int>();
numbers.Add(5);
numbers.Add(15);
numbers.Add(25);
numbers.Add(35);
Console.WriteLine("You are added total number: {0}",numbers.Count);
foreach (int number in numbers)
{
Console.WriteLine("Your adding Number are: {0}", number);
}
Ответы:
На самом деле, строго говоря, все, что вам нужно использовать,
foreach
- это общедоступныйGetEnumerator()
метод, который возвращает что-то вместе сbool MoveNext()
методом и? Current {get;}
свойством. Однако наиболее распространенное значение этого слова - «что-то, что реализуетIEnumerable
/IEnumerable<T>
, возвращаяIEnumerator
/IEnumerator<T>
.Косвенно, это включает в себя все , что инвентарь
ICollection
/ICollection<T>
, например, что - нибудь подобноеCollection<T>
,List<T>
массивы (T[]
) и т.д. Таким образом , любой стандартный «сбор данных», как правило , поддерживаютforeach
.Для доказательства первого пункта отлично работает следующее:
using System; class Foo { public int Current { get; private set; } private int step; public bool MoveNext() { if (step >= 5) return false; Current = step++; return true; } } class Bar { public Foo GetEnumerator() { return new Foo(); } } static class Program { static void Main() { Bar bar = new Bar(); foreach (int item in bar) { Console.WriteLine(item); } } }
Как это работает?
Цикл foreach вроде
foreach(int i in obj) {...}
kinda означает:var tmp = obj.GetEnumerator(); int i; // up to C# 4.0 while(tmp.MoveNext()) { int i; // C# 5.0 i = tmp.Current; {...} // your code }
Однако есть и вариации. Например, если перечислитель (tmp) поддерживает
IDisposable
, он тоже используется (аналогичноusing
).Обратите внимание на разницу в размещении объявления "
int i
" внутри (C # 5.0) и вне (до C # 4.0) цикла. Это важно, если вы используетеi
анонимный метод / лямбду внутри своего блока кода. Но это уже другая история ;-pисточник
for-loop
(вы можете увидеть это при работе с IL).Из MSDN :
Итак, если у вас есть массив, вы можете использовать оператор foreach для итерации по массиву, например:
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 }; foreach (int i in fibarray) { System.Console.WriteLine(i); }
Вы также можете использовать его для итерации по
List<T>
коллекции, например:List<string> list = new List<string>(); foreach (string item in list) { Console.WriteLine(item); }
источник
Согласно сообщению в блоге Duck Notation , используется утиная печать.
источник
Вот документы: Основная статья с массивами с объектами коллекции
Важно отметить, что «Тип элемента коллекции должен быть преобразован в тип идентификатора». Иногда это невозможно проверить во время компиляции и может вызвать исключение времени выполнения, если тип экземпляра не может быть назначен ссылочному типу.
Это вызовет исключение времени выполнения, если в корзине с фруктами есть не Apple, например апельсин.
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() }; foreach(Apple a in fruitBasket)
Это безопасно фильтрует список только для яблок с помощью Enumerable.OfType
foreach(Apple a in fruitBasket.OfType<Apple>() )
источник
IList<ListItem> illi = new List<ListItem>(); ListItem li = null; foreach (HroCategory value in listddlsubcategory) { listddlsubcategoryext = server.getObjectListByColumn(typeof(HroCategory), "Parentid", value.Id); li = new ListItem(); li.Text = value.Description; li.Value = value.Id.ToString(); illi.Add(li); IList<ListItem> newilli = new List<ListItem>(); newilli = SubCatagoryFunction(listddlsubcategoryext, "-->"); foreach (ListItem c in newilli) { illi.Add(c); } }
источник
Полезную информацию по этой теме также можно найти на MSDN . Взяв суть из этой статьи:
Ключевое слово foreach перечисляет коллекцию, выполняя встроенный оператор один раз для каждого элемента в коллекции:
foreach (var item in collection) { Console.WriteLine(item.ToString()); }
Компилятор переводит цикл foreach, показанный в приведенном выше примере, во что-то похожее на эту конструкцию:
IEnumerator<int> enumerator = collection.GetEnumerator(); while (enumerator.MoveNext()) { var item = enumerator.Current; Console.WriteLine(item.ToString()); }
источник
вы можете попробовать это ...
List<int> numbers = new List<int>(); numbers.Add(5); numbers.Add(15); numbers.Add(25); numbers.Add(35); Console.WriteLine("You are added total number: {0}",numbers.Count); foreach (int number in numbers) { Console.WriteLine("Your adding Number are: {0}", number); }
источник