2017-06-13 2 views
-5

Für eine Klasse der Lage sein werden iteriert „foreach“ verwendet wird, sollte es die IEnumerable-Schnittstelle implementieren. aber warum kann diese einfache Klasse ohne Implementierung iteriert werden?Warum muss diese Klasse IEnumerable nicht implementieren?

public class Person 
{ 
    public int Age { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public Person() { } 
    public Person(string firstName, string lastName, int age) 
    { 
     Age = age; 
     FirstName = firstName; 
     LastName = lastName; 
    } 
    public override string ToString() 
    { 
     return string.Format("Name: {0} {1}, Age: {2}", 
     FirstName, LastName, Age); 
    } 
} 

, wenn ich den Code ausführen bekomme ich keine Fehler bezüglich der Verwendung von Foreach

class Program 
{ 
    static void Main(string[] args) 
    { 
     UseGenericList(); 
    } 

    static void UseGenericList() 
    { 
     List<Person> people=new List<Person>() 
     { 
      new Person("Homer","Simpson",47), 
      new Person {FirstName = "Marge",LastName ="Simpson",Age = 45}, 
      new Person {FirstName = "Lisa",LastName = "Simpson",Age = 9}, 
      new Person {FirstName = "Bart",LastName = "Simpson",Age = 8} 
     }; 
     Console.WriteLine("Items in the list:{0}",people.Count); 
     foreach (Person P in people) 
     { 
      Console.WriteLine(P); 
     } 
     Console.WriteLine("Inserting new person"); 
     people.Insert(2,new Person {FirstName ="Maggie",LastName = "Simpson",Age = 2}); 
     Console.WriteLine("items in the list{0}",people.Count); 
     Person[] ArraysOfPeople = people.ToArray(); 
     for (int i = 0; i < ArraysOfPeople.Length; i++) 
     { 
      Console.WriteLine("First Name:{0}",ArraysOfPeople[i].FirstName); 
     } 
    } 

} 

warum?

+11

Da Sie "List " iterieren, sind Sie ** nicht ** iterierende "Person". Iterating Person würde aussehen wie 'foreach (var etwas in personObject)' und natürlich würde es scheitern –

+1

Liste implementieren IEnumerable –

Antwort

8

Sie verwenden List<T> Klasse für die Speicherung Ihrer Person Sammlung, wobei TPerson Klasse ist. Die List<T> Klasse implementiert IEnumerable Schnittstelle. Daher können Sie foreach darauf verwenden

5

Zunächst ist Abhisheks Antwort völlig korrekt; Sie arbeiten mit einem List<T>, das einIEnumerable ist.


jedoch auch wenn es nicht einIEnumerable war, wäre es immer noch funktionieren.

I refer to this SO answer which goes more in depth

Das wichtige Bit:

Noch wichtiger ist aber, die foreach Anweisung in C# können ohne IEnumerable arbeiten beteiligt. Der Compiler kompiliert effektiv die Entry-Eingabe für die Namen GetEnumerator(), Current und MoveNext(). Dies war in erster Linie, um eine stark typisierte (und nicht boxende) Iteration in C# 1 vor Generika zu ermöglichen. Weitere Informationen finden Sie in Abschnitt 8.8.4 der C# 3-Spezifikation.

Mit anderen Worten, es ist nicht erforderlich, IEnumerable zu implementieren, solange die Klasse die erforderlichen Methoden zur Verfügung stellt!

Es wird natürlich immer noch dringend empfohlen, einfach IEnumerable zu implementieren, aber es ist technisch nicht erforderlich.

0

Um mehr zu klären, die Anweisung Sie verwenden, dh

foreach (Person P in people) 
{ 
    Console.WriteLine(P); 
} 

Menschen hier ist Liste der Personen, die den Namen Volk oder etwas anderes für Klarheit dh Liste und Sie Liste implementiert IEnumerable, die ein Verfahren namens haben sollten GetEnumerator

Anfänglich wird der Enumerator vor dem ersten Element positioniert in die Sammlung. Die Reset-Methode bringt den Enumerator auch zurück zu dieser Position. An dieser Position ist die Eigenschaft Current nicht definiert. Daher müssen Sie die MoveNext-Methode aufrufen, um den Enumerator auf das erste Element der Auflistung vor dem Lesen des Werts Current.

Current gibt das gleiche Objekt zurück, bis entweder MoveNext oder Reset aufgerufen wird. MoveNext setzt Current auf das nächste Element.

Wenn MoveNext das Ende der Auflistung überschreitet, wird der Enumerator nach dem letzten Element in der Auflistung positioniert und MoveNext gibt false zurück. Wenn sich der Enumerator an dieser Position befindet, geben nachfolgende Aufrufe von MoveNext ebenfalls false zurück. Wenn der letzte Aufruf von MoveNext den Wert false zurückgibt, ist Current nicht definiert. Um Current erneut auf das erste Element der Sammlung zu setzen, können Sie Reset aufrufen, gefolgt von MoveNext.

Weitere unkonventionelle indirekte Lernen beziehen sich auf Eric's Blog

Man könnte denken, dass, um eine foreach-Schleife zu verwenden, die Sammlung Sie über iterieren IEnumerable oder IEnumerable<T> implementieren müssen. Aber wie sich herausstellt, ist das eigentlich keine Voraussetzung. Was ist erforderlich ist, dass der Typ der Auflistung muss eine öffentliche Methode namens GetEnumerator, und das muss einen Typ zurückgegeben werden, die eine öffentliche Eigenschaft Getter namens Current und eine öffentliche Methode MoveNext hat, die gibt einen Bool zurück. Wenn der Compiler feststellen kann, dass alle Anforderungen erfüllt sind, wird der Code generiert, um diese Methoden zu verwenden. Nur wenn diese Anforderungen nicht erfüllt sind, überprüfen wir, ob das Objekt IEnumerable oder IEnumerable implementiert.

+0

Ich denke, die Benennung ist in Ordnung ... "Menschen" ist der Plural von "Person". –

Verwandte Themen