La documentazione ufficiale mi sembra semplice:
The foreach
statement repeats a group of embedded statements for each element in an array or an object collection that implements the System.Collections.IEnumerable
or System.Collections.Generic.IEnumerable<T>
interface.
Si noti che la risposta di kai , supportata dalla specifica del linguaggio C #, mostra che la documentazione è troppo restrittiva: non è necessario implementare una di queste interfacce per utilizzare una classe con foreach
. Questi sono dettagli di implementazione che sono interessanti da soli, ma non pertinenti per la tua domanda originale, dal momento che nel tuo codice di esempio, stai effettivamente utilizzando un IEnumerable
.
Quello che succede è che la sequenza che usi è una matrice, e secondo la documentazione , sottolineatura mia:
Array types are reference types derived from the abstract base type Array
. Since this type implements IEnumerable
and IEnumerable<T>
, you can use foreach
iteration on all arrays in C#.
Allo stesso modo, puoi consultare la definizione di Array
classe :
public abstract class Array : ICloneable, IList, ICollection,
IEnumerable, IStructuralComparable, IStructuralEquatable
Vedi IEnumerable
tra le interfacce?
Più interessante, esplorando il risultato di typeof(int[])
ti fornisce questo elenco per la proprietà ImplementedInterfaces
:
-
typeof(ICloneable)
-
typeof(IList)
-
typeof(ICollection)
-
typeof(IEnumerable)
-
typeof(IStructuralComparable)
-
typeof(IStructuralEquatable)
-
typeof(IList<Int32>)
-
typeof(ICollection<Int32>)
-
typeof(IEnumerable<Int32>)
-
typeof(IReadOnlyList<Int32>)
-
typeof(IReadOnlyCollection<Int32>)
dove puoi vedere anche le interfacce generiche aggiuntive. (Questo spiega anche perché puoi scrivere IList<int> a = new[] { 1, 2, 3 };
.)
Allo stesso modo, List<T>
, ConcurrentQueue<T>
, ecc. implementa IEnumerable
e Enumerable<T>
.
Quindi quando lo dici:
And also , arrays are working without implementing IEnumerable.
questo semplicemente non è vero. Le matrici sono che implementano IEnumerable
. Per quanto riguarda:
I have following class that didnt implement IEnumerable but working perfectly with foreach.
sarebbe interessante vedere il codice reale (quello che hai nella tua domanda usa un array). Quello che probabilmente sta succedendo è che la tua classe, senza dichiarare esplicitamente IEnumerable
o IEnumerable<T>
tra le sue interfacce, implementa un'interfaccia più specifica, come ICollection<T>
, che, a sua volta, eredita da IEnumerable
:
public interface ICollection<T> : IEnumerable<T>, IEnumerable
E se no, beh, probabilmente sei nel caso illustrato nella risposta di kai.