Starając się, aby rzeczy były „proste”, .NET ma tylko jedną ogólną / nie-ogólną parę interfejsów dla rzeczy, które są wyliczane przez wywołanie, GetEnumerator()
a następnie użycie MoveNext
i Current
na otrzymanym z nich obiekcie, mimo że istnieją co najmniej cztery rodzaje obiektów które powinny obsługiwać tylko te metody:
- Rzeczy, które można wymienić przynajmniej raz, ale niekoniecznie więcej.
- Rzeczy, które można wyliczyć dowolną liczbę razy w kontekstach o swobodnym wątku, ale mogą dowolnie dawać różne treści za każdym razem
- Rzeczy, które można wyliczyć dowolną liczbę razy w kontekstach o swobodnym wątku, ale mogą zagwarantować, że jeśli kod, który je wylicza wielokrotnie, nie wywoła żadnych metod mutacji, wszystkie wyliczenia zwrócą tę samą treść.
- Rzeczy, które można wyliczyć dowolną liczbę razy, i gwarantują, że zwrócą tę samą treść za każdym razem, o ile istnieją.
Każde wystąpienie, które spełnia jedną z definicji o wyższym numerze, spełni również wszystkie niższe, ale kod, który wymaga obiektu spełniającego jedną z wyższych definicji, może ulec awarii, jeśli zostanie podany jeden z niższych.
Wydaje się, że Microsoft zdecydował, że klasy, które implementują, IEnumerable<T>
powinny spełniać drugą definicję, ale nie są zobowiązane do spełnienia niczego wyższego. Prawdopodobnie nie ma zbyt wielu powodów, aby coś, co mogłoby spełnić tylko pierwszą definicję, powinno IEnumerable<T>
raczej zostać wprowadzone IEnumerator<T>
; jeśli foreach
pętle mogłyby zaakceptować IEnumerator<T>
, sensownym byłoby, aby rzeczy, które można wymienić tylko raz, wystarczy zaimplementować ten ostatni interfejs. Niestety typy, które tylko implementują, IEnumerator<T>
są mniej wygodne w użyciu w C # i VB.NET niż typy, które mają GetEnumerator
metodę.
W każdym razie, chociaż byłoby użyteczne, gdyby istniały różne wyliczalne typy rzeczy, które mogłyby dawać różne gwarancje i / lub standardowy sposób, aby zapytać instancję, która implementuje IEnumerable<T>
jakie gwarancje może uczynić, żadne takie typy jeszcze nie istnieją.