2014-07-22 6 views
13

Ich bereite mich auf meine C# EXAM. Ich bin verwirrt über die Antwort auf diese Frage:Was ist der Grund für die Implementierung von IEnumerable und IEnumerator

Ein Programm die IEnumerable und IEnumerator Schnittstellen verwenden können, um zu tun, welche der folgenden?

a. Verwenden Sie MoveNext und Reset, um sich durch eine Liste von Objekten zu bewegen.
b. Verwenden Sie foreach, um sich durch eine Liste von Objekten zu bewegen.
c. Durch eine Liste von Objekten nach Index navigieren.
d. Verwenden Sie die yield return-Anweisung, um eine Liste von Objekten für die Iteration zu erstellen.

Meine Antwort war b). Aber das Buch: MCSD Certification Toolkit sagt, es ist ein).

Kann mir jemand sagen warum? Ich erkenne, dass Sie die Enumerator mit GetEnumerator() erhalten können und dann die Methoden MoveNext und Reset aufrufen, um durch die Liste zu gehen (und Current verwenden, um auf das aktuelle Element zuzugreifen, auf das der Iterator verweist). Aber implementiert IEnumerable und IEnumerator nicht den Grund für ein Objekt in einer foreach Schleife verwendet werden?

+1

Von MSDN: 'Es ist eine bewährte Methode IEnumerable und IEnumerator auf Ihrer Sammlung Klassen zu implementieren, um die foreach zu ermöglichen (For Each in Visual Basic) Syntax wird jedoch die Umsetzung IEnumerable –

+1

nicht so required.', Sie sagen, dass, weil die Frage IEnumerable und IEnUMERATOR sagt, es a) sein sollte. Vielen Dank, Hank. Du hast meinen Tag gerettet! – user3509153

+6

Ich hasse diese Art von Fragen. Sie testen Sie auf Ihre Fähigkeit, vage/unklare Fragen zu entschlüsseln und nicht Ihr Wissen zu diesem Thema. –

Antwort

4

Die richtige Antwort ist ein und das ist klar, wenn man einen Blick auf die Definitionen der Schnittstellen nehmen:

[GuidAttribute("496B0ABE-CDEE-11d3-88E8-00902754C43A")] 
[ComVisibleAttribute(true)] 
public interface IEnumerable 
{ 
    IEnumerator GetEnumerator(); 
} 

Und

[ComVisibleAttribute(true)] 
[GuidAttribute("496B0ABF-CDEE-11d3-88E8-00902754C43A")] 
public interface IEnumerator 
{ 
    Object Current { get; } 
    bool MoveNext(); 
    void Reset(); 
} 

Wie Sie hier bemerken, wenn ein Typ Implementiert die IEnumerable Schnittstelle, sollte es eine Methode haben, die einen Enumerator zurückgibt, ein Objekt, das die IEnumerator Schnittstelle implementiert.

Dann wird die Schnittstelle IEnumerator hat eine Eigenschaft genannt, die das aktuelle Objekt hält, wenn wir durch eine Sammlung und zwei Verfahren iterieren, die MoveNext und die Reset. Unter der Haube, wenn wir durch eine Sammlung iterieren, wird zuerst die Methode des Iterators MoveNext genannt. Wenn das wahr ist, erhalten wir das erste Element - das ist das aktuelle Objekt. Dann wird die Methode MoveNext immer wieder aufgerufen, bis sie false zurückgibt. Jedes Mal, wenn MoveNext aufgerufen wird, erhalten wir ein Objekt aus der Sammlung, die wir durchlaufen.

Warum haben wir die Reset Methode?

Wie es in MSDN angegeben:

Setzt den Enumerator in seine Ausgangsposition, die in der Sammlung, bevor die erste Element ist.

+0

Aber wie genau begünstigt dies a) gegenüber b)? Ich dachte früher, dass 'foreach()' diese Schnittstellen benötigt. Es benötigt genau ihre Funktionalität. –

+0

@HenkHolterman Ich denke, dass a gegenüber b bevorzugt sein sollte, weil foreach diese Methoden verwendet, um die Iteration durchzuführen, die foreach tut. Es bezieht sich auf die Interna. Selbst wenn wir nicht die 'foreach()' Aussage hätten, wären wir in der Lage gewesen, sie mit diesen Methoden zu imitieren. Ich stimme zu 100% damit überein, dass 'foreach()' von der Sammlung verlangt, diese Schnittstellen zu implementieren. – Christos

1

Wenn Sie die Schnittstelle implementieren, sind Sie für den Auftrag zustimmen: Movenext und Reset. Die anderen Optionen für die Frage beziehen sich auf konkrete Klassen, die die Schnittstelle implementieren.

0

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 false zurückgibt, ist Current nicht definiert. Um Current erneut auf das erste Element der Auflistung zu setzen, können Sie Reset aufrufen, gefolgt von MoveNext.

click here for detailed explanation

Verwandte Themen