2014-07-22 14 views
13

Przygotowuję się do mojego C# EXAM. Jestem mylić o odpowiedź na to pytanie:Jaki jest powód implementacji IEnumerable i IEnumerator

Program można wykorzystać interfejsy IEnumerable i IEnumerator zrobić które z poniższych stwierdzeń?

a. Użyj funkcji MoveNext i Reset, aby poruszać się po liście obiektów.
b. Użyj foreach, aby poruszać się po liście obiektów.
c. Przejdź przez listę obiektów według indeksu.
d. Użyj instrukcji return return, aby utworzyć listę obiektów do iteracji.

Moja odpowiedź była b). Ale książka: MCSD Certification Toolkit mówi, że jest to a).

Czy ktoś może mi powiedzieć, dlaczego? Rozumiem, że można uzyskać Enumerator przy użyciu GetEnumerator(), a następnie wywołać metody MoveNext i Reset, aby przejść przez listę (i użyć Current, aby uzyskać dostęp do bieżącego elementu, do którego odnosi się iterator). Ale nie implementuje IEnumerable i IEnumerator powodów, dla których obiekt ma być używany w pętli foreach?

+1

Od MSDN: 'Jest to najlepsze praktyki do wdrożenia IEnumerable i IEnumerator na swoich klasach zbiórki w celu umożliwienia foreach (dla każdego Visual Basic) składni, jednak wdrożenie IEnumerable nie required.' –

+1

Więc, mówisz tak, ponieważ pytanie mówi zarówno IEnumerable i IEnUMERATOR, powinno być a). Dziękuję bardzo Hank. Zrobiłeś mój dzień! – user3509153

+6

Nienawidzę tego rodzaju pytań. Sprawdzają, czy potrafisz odcyfrować niejasne/niejasne pytania, a nie swoją wiedzę na ten temat. –

Odpowiedz

4

Prawidłowa odpowiedź to i to jest oczywiste, jeśli spojrzeć na definicjach interfejsów:

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

And

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

Jak można zauważyć tutaj, gdy typ implementuje interfejs IEnumerable, powinien mieć metodę, która zwróci moduł wyliczający, obiekt implementujący interfejs IEnumerator.

Następnie interfejs o nazwie ma jedną właściwość, która przechowuje bieżący obiekt, gdy przechodzimy przez kolekcję i dwie metody: MoveNext i Reset. Pod maską, kiedy przechodzimy przez kolekcję, najpierw wywoływana jest metoda Iteratora o nazwie MoveNext. Jeśli to prawda, otrzymujemy pierwszy element - to jest bieżący obiekt. Następnie wywoływana jest metoda o nazwie MoveNext, która jest wywoływana ponownie, dopóki nie zwróci false. Za każdym razem, gdy wywoływana jest nazwa MoveNext, otrzymujemy obiekt z kolekcji, przechodzimy przez iterację.

Dlaczego mamy metodę Reset?

Jak podano w MSDN:

Zestawy numeratora do położenia początkowego, który jest przed pierwszym element zbioru.

+0

Ale jak dokładnie to sprzyja a) w b)? Kiedyś myślałem, że 'foreach()' potrzebuje tych interfejsów. To wymaga dokładnie ich funkcjonalności. –

+0

@HenkHolterman Myślę, że powinno być faworyzowane przez b, ponieważ foreach używa tych metod do iteracji, którą robi foreach. Odnosi się do elementów wewnętrznych. Nawet gdybyśmy nie mieli stwierdzenia foreach(), bylibyśmy w stanie naśladować to za pomocą tych metod. Zgadzam się w 100% z Tobą, że 'foreach()' wymaga od kolekcji implementacji tych interfejsów. – Christos

1

Po zaimplementowaniu interfejsu zgadzasz się na umowę: PrzenieśNext i Resetuj. Pozostałe opcje pytania odnoszą się do konkretnych klas implementujących interfejs.

0

Jeśli klasa MoveNext przechodzi przez koniec kolekcji, moduł wyliczający jest pozycjonowany po ostatnim elemencie kolekcji, a parametr MoveNext zwraca wartość false. Gdy moduł wyliczający znajduje się w tej pozycji, kolejne wywołania funkcji MoveNext również zwracają wartość false. Jeśli ostatnie wywołanie funkcji MoveNext zwraca wartość false, wartość Current jest niezdefiniowana. Aby ponownie ustawić Current na pierwszy element kolekcji, możesz wywołać Reset, a następnie MoveNext.

click here for detailed explanation

Powiązane problemy