Quali tipi di classi possono utilizzare i foreach
loop?
Risposte:
In realtà, in senso stretto, tutto ciò che devi usare foreach
è un GetEnumerator()
metodo pubblico che restituisca qualcosa con un bool MoveNext()
metodo e una ? Current {get;}
proprietà. Tuttavia, il significato più comune di questo è "qualcosa che implementa IEnumerable
/ IEnumerable<T>
, restituendo un IEnumerator
/ IEnumerator<T>
.
Implicitamente, questo include tutto ciò che implementa ICollection
/ ICollection<T>
, come qualcosa di simile Collection<T>
, List<T>
, array ( T[]
), ecc Quindi, qualsiasi "raccolta di dati" standard generalmente sostenere foreach
.
Per la prova del primo punto, quanto segue funziona perfettamente:
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);
}
}
}
Come funziona?
Un ciclo foreach come foreach(int i in obj) {...}
un pò equivale a:
var tmp = obj.GetEnumerator();
int i; // up to C# 4.0
while(tmp.MoveNext()) {
int i; // C# 5.0
i = tmp.Current;
{...} // your code
}
Tuttavia, ci sono variazioni. Ad esempio, se l'enumeratore (tmp) supporta IDisposable
, viene utilizzato anche (simile a using
).
Notare la differenza nel posizionamento della " int i
" dichiarazione all'interno (C # 5.0) e all'esterno (su C # 4.0) del ciclo. È importante se usi i
un metodo anonimo / lambda all'interno del tuo blocco di codice. Ma questa è un'altra storia ;-p
for-loop
(puoi vederlo quando lavori con IL).
Da MSDN :
L'
foreach
istruzione ripete un gruppo di istruzioni incorporate per ogni elemento in un array o in una raccolta di oggetti . L'foreach
istruzione viene utilizzata per scorrere la raccolta per ottenere le informazioni desiderate, ma non deve essere utilizzata per modificare il contenuto della raccolta per evitare effetti collaterali imprevedibili. (enfasi mia)
Quindi, se hai un array, puoi usare l'istruzione foreach per iterare attraverso l'array, in questo modo:
int[] fibarray = new int[] { 0, 1, 2, 3, 5, 8, 13 };
foreach (int i in fibarray)
{
System.Console.WriteLine(i);
}
Puoi anche usarlo per scorrere una List<T>
raccolta, in questo modo:
List<string> list = new List<string>();
foreach (string item in list)
{
Console.WriteLine(item);
}
Secondo il post del blog Duck Notation , viene utilizzata la dattilografia.
Ecco i documenti: articolo principale con array con oggetti di raccolta
È importante notare che "Il tipo dell'elemento della raccolta deve essere convertibile nel tipo di identificatore". Questo a volte non può essere verificato in fase di compilazione e può generare un'eccezione di runtime se il tipo di istanza non è assegnabile al tipo di riferimento.
Questo genererà un'eccezione di runtime se nel cesto della frutta è presente una mela non, come un'arancia.
List<Fruit> fruitBasket = new List<Fruit>() { new Apple(), new Orange() };
foreach(Apple a in fruitBasket)
Questo filtra in modo sicuro l'elenco solo per le mele utilizzando 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);
}
}
Informazioni utili su questo argomento si possono trovare anche su MSDN . Prendendo l'essenza da quell'articolo:
La parola chiave foreach enumera una raccolta, eseguendo l'istruzione incorporata una volta per ogni elemento nella raccolta:
foreach (var item in collection)
{
Console.WriteLine(item.ToString());
}
Il compilatore traduce il ciclo foreach mostrato nell'esempio sopra in qualcosa di simile a questo costrutto:
IEnumerator<int> enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
Console.WriteLine(item.ToString());
}
puoi provare questo ...
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);
}