GetEnumeratorObsługa rozszerzeń dla foreach pętli.Extension GetEnumerator support for foreach loops.
PodsumowanieSummary
Zezwalaj na pętle foreach do rozpoznawania metody GetEnumerator, która w przeciwnym razie spełnia wzorzec foreach, i pętlę na wyrażeniu, gdy w przeciwnym razie mógłby być błędem.Allow foreach loops to recognize an extension method GetEnumerator method that otherwise satisfies the foreach pattern, and loop over the expression when it would otherwise be an error.
MotywacjaMotivation
Spowoduje to przełączenie instrukcji foreach w sposób wbudowany z sposobem implementacji innych funkcji w języku C#, w tym z międzychmurowego i opartego na wzorcu.This will bring foreach inline with how other features in C# are implemented, including async and pattern-based deconstruction.
Szczegółowy projektDetailed design
Zmiana specyfikacji jest stosunkowo prosta.The spec change is relatively straightforward. Modyfikujemy The foreach statement sekcję do tego tekstu:We modify The foreach statement section to this text:
Przetwarzanie w czasie kompilacji instrukcji foreach najpierw określa Typ kolekcji* , Typ modułu wyliczającego i _ Typ elementu* wyrażenia.The compile-time processing of a foreach statement first determines the collection type _, _enumerator type* and _ element type* of the expression. To obliczanie jest przeprowadzane w następujący sposób:This determination proceeds as follows:
Jeśli typ
Xwyrażenia jest typem tablicy, istnieje niejawna konwersja odwołania zXdoIEnumerableinterfejsu (ponieważSystem.Arrayimplementuje ten interfejs).If the typeXof expression is an array type then there is an implicit reference conversion fromXto theIEnumerableinterface (sinceSystem.Arrayimplements this interface). Typ kolekcji _ jestIEnumerableinterfejsem, _typem modułu wyliczającego*_ jestIEnumeratorinterfejs, a Typ elementu _ * jest typem elementu typu tablicyX.The collection type _ is theIEnumerableinterface, the _enumerator type_ is theIEnumeratorinterface and the _ element type is the element type of the array typeX.Jeśli typem
Xwyrażenia jestdynamic, istnieje niejawna konwersja z wyrażenia doIEnumerableinterfejsu (niejawne konwersje dynamiczne).If the typeXof expression isdynamicthen there is an implicit conversion from expression to theIEnumerableinterface (Implicit dynamic conversions). Typ kolekcji _ jestIEnumerableinterfejsem, a _typem modułu wyliczającego*_ jestIEnumeratorinterfejs.The collection type _ is theIEnumerableinterface and the _enumerator type*_ is theIEnumeratorinterface. JeślivarIdentyfikator jest określony jako _local_variable_type *, wówczas typem elementu jestdynamic, w przeciwnym razieobject.If thevaridentifier is given as the _local_variable_type* then the element type isdynamic, otherwise it isobject.W przeciwnym razie Ustal, czy typ
Xma odpowiedniąGetEnumeratormetodę:Otherwise, determine whether the typeXhas an appropriateGetEnumeratormethod:
- Wykonaj wyszukiwanie elementów członkowskich w typie
Xz identyfikatoremGetEnumeratori bez argumentów typu.Perform member lookup on the typeXwith identifierGetEnumeratorand no type arguments. Jeśli wyszukiwanie elementu członkowskiego nie produkuje dopasowania lub tworzy niejednoznaczność lub tworzy dopasowanie, które nie jest grupą metod, należy sprawdzić, czy wyliczalny interfejs został opisany poniżej.If the member lookup does not produce a match, or it produces an ambiguity, or produces a match that is not a method group, check for an enumerable interface as described below. Zaleca się, aby ostrzeżenie było wydawane, gdy wyszukiwanie elementów członkowskich produkuje wszystkie elementy poza grupą metod lub nie odpowiada.It is recommended that a warning be issued if member lookup produces anything except a method group or no match.- Wykonaj rozwiązanie przeciążenia przy użyciu grupy metod i pustej listy argumentów.Perform overload resolution using the resulting method group and an empty argument list. Jeśli rozwiązanie przeciążenia skutkuje brakiem odpowiednich metod, wyniki są niejednoznaczne lub mają jedną najlepszą metodę, ale ta metoda jest statyczna lub nie jest publiczna, Wyszukaj wyliczalny interfejs zgodnie z poniższym opisem.If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, check for an enumerable interface as described below. Zaleca się, aby ostrzeżenie było wydawane, jeśli rozwiązanie przeciążania produkuje wszystko, z wyjątkiem jednoznacznej metody wystąpienia publicznego lub nie ma zastosowania do odpowiednich metod.It is recommended that a warning be issued if overload resolution produces anything except an unambiguous public instance method or no applicable methods.
- Jeśli zwracany typ
EGetEnumeratormetody nie jest klasą, strukturą lub typem interfejsu, jest generowany błąd i nie są podejmowane żadne dalsze kroki.If the return typeEof theGetEnumeratormethod is not a class, struct or interface type, an error is produced and no further steps are taken.- Wyszukiwanie elementu członkowskiego jest wykonywane na
Ez identyfikatoremCurrenti bez argumentów typu.Member lookup is performed onEwith the identifierCurrentand no type arguments. Jeśli wyszukiwanie elementu członkowskiego nie powoduje dopasowania, wynikiem jest błąd lub wynikiem jest wszystko z wyjątkiem właściwości wystąpienia publicznego, która umożliwia odczytywanie, zostanie wygenerowany błąd i nie są podejmowane żadne dalsze kroki.If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.- Wyszukiwanie elementu członkowskiego jest wykonywane na
Ez identyfikatoremMoveNexti bez argumentów typu.Member lookup is performed onEwith the identifierMoveNextand no type arguments. Jeśli wyszukiwanie elementu członkowskiego nie powoduje dopasowania, wynikiem jest błąd lub wynikiem jest wszystko poza grupą metod, zostanie wygenerowany błąd i nie są podejmowane żadne dalsze kroki.If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.- Rozpoznanie przeciążenia jest wykonywane w grupie metod z pustą listą argumentów.Overload resolution is performed on the method group with an empty argument list. Jeśli rozwiązanie przeciążenia skutkuje brakiem odpowiednich metod, wyniki są niejednoznaczne lub mają jedną najlepszą metodę, ale ta metoda jest statyczna lub nie jest publiczna lub jej typem zwracanym jest
boolbłąd i nie są podejmowane żadne dalsze kroki.If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is notbool, an error is produced and no further steps are taken.- Typ kolekcji _ ma wartość
X, _Typ wyliczającego_ toE, a _ element Type jest typemCurrentwłaściwości.The collection type _ isX, the _enumerator type_ isE, and the _ element type is the type of theCurrentproperty.W przeciwnym razie Sprawdź, czy wyliczalny interfejs:Otherwise, check for an enumerable interface:
- Jeśli wśród wszystkich typów
Ti, dla których istnieje niejawna konwersja zXdoIEnumerable<Ti>, istnieje unikatowy typ,TktóryTnie jestdynamici dla wszystkich pozostałychTiistnieje niejawna konwersja zIEnumerable<T>do naIEnumerable<Ti>, a następnie Typ kolekcji* _ jest interfejsemIEnumerable<T>, typem modułu wyliczającego jest interfejsIEnumerator<T>, a Typ elementu _ * ma wartośćT.If among all the typesTifor which there is an implicit conversion fromXtoIEnumerable<Ti>, there is a unique typeTsuch thatTis notdynamicand for all the otherTithere is an implicit conversion fromIEnumerable<T>toIEnumerable<Ti>, then the collection type _ is the interfaceIEnumerable<T>, the _enumerator type_ is the interfaceIEnumerator<T>, and the _ element type isT.- W przeciwnym razie, jeśli istnieje więcej niż jeden taki typ
T, zostanie wygenerowany błąd i nie zostaną wykonane żadne dalsze kroki.Otherwise, if there is more than one such typeT, then an error is produced and no further steps are taken.- W przeciwnym razie, jeśli istnieje niejawna konwersja z
XdoSystem.Collections.IEnumerableinterfejsu, wówczas Typ kolekcji* _ jest tym interfejsem, typem modułu wyliczającego jest interfejsSystem.Collections.IEnumerator, a Typ elementu _ * ma wartośćobject.Otherwise, if there is an implicit conversion fromXto theSystem.Collections.IEnumerableinterface, then the collection type _ is this interface, the _enumerator type_ is the interfaceSystem.Collections.IEnumerator, and the _ element type isobject.W przeciwnym razie Ustal, czy typ "X" ma odpowiednią
GetEnumeratormetodę rozszerzenia:Otherwise, determine whether the type 'X' has an appropriateGetEnumeratorextension method:
- Wykonaj wyszukiwanie metody rozszerzenia dla typu
Xz identyfikatoremGetEnumerator.Perform extension method lookup on the typeXwith identifierGetEnumerator. Jeśli wyszukiwanie elementu członkowskiego nie produkuje dopasowania lub tworzy niejednoznaczność lub tworzy dopasowanie, które nie jest grupą metod, zostanie wygenerowany błąd i nie są podejmowane żadne dalsze kroki.If the member lookup does not produce a match, or it produces an ambiguity, or produces a match which is not a method group, an error is produced and no further steps are taken. Zaleca się, aby ostrzeżenie było wyświetlane, gdy wyszukiwanie elementów członkowskich produkuje wszystkie elementy poza grupą metod lub nie odpowiada.It is recommended that a warning be issues if member lookup produces anything except a method group or no match.- Wykonaj rozwiązanie przeciążania przy użyciu grupy metod i jednego argumentu typu
X.Perform overload resolution using the resulting method group and a single argument of typeX. Jeśli rozwiązanie przeciążania nie daje odpowiednich metod, wynikiem jest niejednoznaczność lub daje jedną najlepszą metodę, ale ta metoda nie jest dostępna, zostanie wygenerowany błąd.If overload resolution produces no applicable methods, results in an ambiguity, or results in a single best method but that method is not accessible, an error is produced an no further steps are taken.
- To rozwiązanie zezwala na pierwszy argument, który ma zostać przesłany przez ref
X, jeśli jest typem struktury, a rodzajem ref jestin.This resolution permits the first argument to be passed by ref ifXis a struct type, and the ref kind isin.- Jeśli zwracany typ
EGetEnumeratormetody nie jest klasą, strukturą lub typem interfejsu, jest generowany błąd i nie są podejmowane żadne dalsze kroki.If the return typeEof theGetEnumeratormethod is not a class, struct or interface type, an error is produced and no further steps are taken.- Wyszukiwanie elementu członkowskiego jest wykonywane na
Ez identyfikatoremCurrenti bez argumentów typu.Member lookup is performed onEwith the identifierCurrentand no type arguments. Jeśli wyszukiwanie elementu członkowskiego nie powoduje dopasowania, wynikiem jest błąd lub wynikiem jest wszystko z wyjątkiem właściwości wystąpienia publicznego, która umożliwia odczytywanie, zostanie wygenerowany błąd i nie są podejmowane żadne dalsze kroki.If the member lookup produces no match, the result is an error, or the result is anything except a public instance property that permits reading, an error is produced and no further steps are taken.- Wyszukiwanie elementu członkowskiego jest wykonywane na
Ez identyfikatoremMoveNexti bez argumentów typu.Member lookup is performed onEwith the identifierMoveNextand no type arguments. Jeśli wyszukiwanie elementu członkowskiego nie powoduje dopasowania, wynikiem jest błąd lub wynikiem jest wszystko poza grupą metod, zostanie wygenerowany błąd i nie są podejmowane żadne dalsze kroki.If the member lookup produces no match, the result is an error, or the result is anything except a method group, an error is produced and no further steps are taken.- Rozpoznanie przeciążenia jest wykonywane w grupie metod z pustą listą argumentów.Overload resolution is performed on the method group with an empty argument list. Jeśli rozwiązanie przeciążenia skutkuje brakiem odpowiednich metod, wyniki są niejednoznaczne lub mają jedną najlepszą metodę, ale ta metoda jest statyczna lub nie jest publiczna lub jej typem zwracanym jest
boolbłąd i nie są podejmowane żadne dalsze kroki.If overload resolution results in no applicable methods, results in an ambiguity, or results in a single best method but that method is either static or not public, or its return type is notbool, an error is produced and no further steps are taken.- Typ kolekcji _ ma wartość
X, _Typ wyliczającego_ toE, a _ element Type jest typemCurrentwłaściwości.The collection type _ isX, the _enumerator type_ isE, and the _ element type is the type of theCurrentproperty.W przeciwnym razie zostanie wygenerowany błąd i nie są podejmowane żadne dalsze kroki.Otherwise, an error is produced and no further steps are taken.
W przypadku programu await foreach reguły są modyfikowane w podobny sposób.For await foreach, the rules are similarly modified. Jedyną zmianą, która jest wymagana do tej specyfikacji, jest usunięcie Extension methods do not contribute. wiersza z opisu, ponieważ pozostała część tej specyfikacji jest oparta na powyższych regułach z różnymi nazwami zastępowanymi dla metod wzorca.The only change that is required to that spec is removing the Extension methods do not contribute. line from the description, as the rest of that spec is based on the above rules with different names substituted for the pattern methods.
WadyDrawbacks
Każda zmiana dodaje do języka dodatkową złożoność, dzięki czemu może to spowodować, że nie zaprojektowano go do foreach foreach postaci Ed, np Range ..Every change adds additional complexity to the language, and this potentially allows things that weren't designed to be foreached to be foreached, like Range.
AlternatywyAlternatives
Nic nie robi.Doing nothing.
Nierozwiązane pytaniaUnresolved questions
Brak w tym momencie.None at this point.