Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Unterstützung für die Erweiterung
Hinweis
Dieser Artikel ist eine Feature-Spezifikation. Die Spezifikation dient als Designdokument für das Feature. Es enthält vorgeschlagene Spezifikationsänderungen sowie Informationen, die während des Entwurfs und der Entwicklung des Features erforderlich sind. Diese Artikel werden veröffentlicht, bis die vorgeschlagenen Spezifikationsänderungen abgeschlossen und in die aktuelle ECMA-Spezifikation aufgenommen werden.
Es kann einige Abweichungen zwischen der Feature-Spezifikation und der abgeschlossenen Implementierung geben. Diese Unterschiede werden in den entsprechenden Hinweisen zum Language Design Meeting (LDM) erfasst.
Weitere Informationen zum Prozess für die Aufnahme von Funktions-Speclets in den C#-Sprachstandard finden Sie im Artikel zu den Spezifikationen.
Champion-Problem: https://github.com/dotnet/csharplang/issues/3194
Zusammenfassung
Erlauben, dass foreach-Schleifen eine GetEnumerator-Methode erkennen, die ansonsten dem foreach-Muster entspricht, und über den Ausdruck iterieren, wenn ansonsten ein Fehler auftreten würde.
Motivation
Dies bringt foreach in Einklang mit der Implementierung anderer Features in C#, einschließlich async und musterbasierter Dekonstruktion.
Detailliertes Design
Die Spezifikationsänderung ist relativ einfach. Wir ändern The foreach statement§13.9.5-Abschnitt in diesen Text:
Die Kompilierungszeitverarbeitung einer foreach-Anweisung bestimmt zuerst den Auflistungstyp, Enumerationstyp und Elementtyp des Ausdrucks. Diese Feststellung erfolgt wie folgt:
Wenn der Typ
Xdes Ausdrucks ein Arraytyp ist, gibt es eine implizite Verweiskonvertierung vonXzurIEnumerable-Schnittstelle (daSystem.Arraydiese Schnittstelle implementiert). Der -Sammlungstyp ist dieIEnumerable-Schnittstelle, der -Enumerationstyp ist dieIEnumerator-Schnittstelle, und der -Elementtyp ist der Elementtyp des Array-TypsX.Wenn der Typ
Xdes Ausdrucks ist,dynamicgibt es eine implizite Konvertierung von Ausdruck in dieIEnumerableSchnittstelle (§10.2.10). Der Sammlungstyp ist dieIEnumerable-Schnittstelle und der Enumerationstyp ist dieIEnumerator-Schnittstelle. Wenn dervar-Bezeichner als local_variable_type angegeben wird, dann ist der Elementtypdynamic, andernfalls ist esobject.Ermitteln Sie andernfalls, ob der Typ
Xüber eine geeigneteGetEnumerator-Methode verfügt:
- Führen Sie die Membersuche für den Typ
Xmit dem BezeichnerGetEnumeratorund ohne Typargumente durch. Wenn die Membersuche keine Übereinstimmung liefert oder eine Mehrdeutigkeit vorliegt oder eine Übereinstimmung liefert, die keine Methodengruppe ist, suchen Sie nach einer aufzählbaren Schnittstelle, wie unten beschrieben. Es wird empfohlen, eine Warnung auszugeben, wenn die Mitgliedersuche etwas anderes als eine Methodengruppe oder keine Übereinstimmung liefert.- Führen Sie die Überladungsauflösung mithilfe der resultierenden Methodengruppe und einer leeren Argumentliste aus. Wenn die Überladungsauflösung zu keiner anwendbaren Methode führt, eine Mehrdeutigkeit verursacht oder lediglich die beste Methode ergibt, die jedoch entweder statisch oder nicht öffentlich ist, prüfen Sie auf eine aufzählbare Schnittstelle, wie unten beschrieben. Es wird empfohlen, dass eine Warnung ausgegeben wird, wenn die Überladungsauflösung nichts anderes als eine eindeutige öffentliche Instanzmethode oder keine anwendbaren Methoden erzeugt.
- Wenn der Rückgabetyp
EderGetEnumerator-Methode keine Klasse, Struktur oder kein Schnittstellentyp ist, wird ein Fehler erzeugt und es werden keine weiteren Schritte ausgeführt.- Membersuche wird bei
Emit dem BezeichnerCurrentund ohne Typargumente durchgeführt. Wenn die Membersuche keine Übereinstimmung ergibt, das Ergebnis ein Fehler ist oder es sich bei dem Ergebnis nicht um eine öffentliche Instanz-Eigenschaft handelt, die das Lesen zulässt, wird ein Fehler erzeugt, und es werden keine weiteren Schritte unternommen.- Membersuche wird bei
Emit dem BezeichnerMoveNextund ohne Typargumente durchgeführt. Wenn die Suche nach einem Mitglied keine Übereinstimmung ergibt oder das Ergebnis etwas anderes als eine Methodengruppe ist, wird ein Fehler erzeugt; und es werden keine weiteren Schritte unternommen.- Die Auflösung von Überladungen wird für die Methodengruppe mit einer leeren Argumentliste durchgeführt. Führt die Überladungsauflösung zu keiner anwendbaren Methode, führt zu einer Mehrdeutigkeit oder führt zu einer einzigen besten Methode, aber diese Methode ist entweder statisch oder nicht öffentlich, oder der Rückgabetyp ist nicht
bool, wird ein Fehler erzeugt, und es werden keine weiteren Schritte ausgeführt.- Der Sammlungstyp ist
X, der Aufzählungstyp istE, und der Elementtyp ist der Typ derCurrent-Eigenschaft.Suchen Sie andernfalls nach einer aufzählbaren Schnittstelle:
- Wenn es unter allen Typen
Ti, für die eine implizite Konvertierung vonXzuIEnumerable<Ti>möglich ist, einen eindeutigen TypTgibt, sodassTnicht identisch mitdynamicist und für alle anderenTieine implizite Konvertierung vonIEnumerable<T>zuIEnumerable<Ti>möglich ist, dann ist der -Sammlungstyp die SchnittstelleIEnumerable<T>, der -Enumerationstyp ist die SchnittstelleIEnumerator<T>und der -Elementtyp istT.- Andernfalls wird bei mehr als einem solchen Typ
Tein Fehler erzeugt und es werden keine weiteren Schritte ausgeführt.- Andernfalls, wenn es eine implizite Konvertierung von
XzurSystem.Collections.IEnumerable-Schnittstelle gibt, dann ist der -Sammlungstyp diese Schnittstelle, der -Enumerator-Typ die SchnittstelleSystem.Collections.IEnumerator, und der -Elementtyp istobject.Ermitteln Sie andernfalls, ob der Typ „X“ über eine geeignete
GetEnumerator-Erweiterungsmethode verfügt.
- Führen Sie die Erweiterungsmethode für den Typ
Xmit BezeichnerGetEnumeratoraus. Wenn die Membersuche keine Übereinstimmung findet, eine Mehrdeutigkeit ergibt oder eine Übereinstimmung liefert, bei der es sich nicht um eine Methodengruppe handelt, tritt ein Fehler auf, und es werden keine weiteren Schritte ausgeführt. Es wird empfohlen, eine Warnung auszugeben, wenn die Membersuche etwas anderes als eine Methodengruppe oder keine Übereinstimmung liefert.- Führen Sie die Überladungsauflösung mit der resultierenden Methodengruppe und einem einzelnen Argument vom Typ
Xaus. Wenn die Überladungsauflösung keine anwendbaren Methoden erzeugt, zu einer Mehrdeutigkeit führt oder eine einzige beste Methode ergibt, diese Methode jedoch nicht zugänglich ist, wird ein Fehler erzeugt, und es werden keine weiteren Schritte ausgeführt.
- Mit dieser Resolution kann das erste Argument als Referenz übergeben werden, wenn
Xein Strukturtyp ist und die Ref-Kategorieinist.- Wenn der Rückgabetyp
EderGetEnumerator-Methode keine Klasse, Struktur oder kein Schnittstellentyp ist, wird ein Fehler erzeugt und es werden keine weiteren Schritte ausgeführt.- Membersuche wird bei
Emit dem BezeichnerCurrentund ohne Typargumente durchgeführt. Wenn die Membersuche keine Übereinstimmung ergibt, das Ergebnis ein Fehler ist oder es sich bei dem Ergebnis nicht um eine öffentliche Instanz-Eigenschaft handelt, die das Lesen zulässt, wird ein Fehler erzeugt, und es werden keine weiteren Schritte unternommen.- Membersuche wird bei
Emit dem BezeichnerMoveNextund ohne Typargumente durchgeführt. Wenn die Suche nach einem Mitglied keine Übereinstimmung ergibt oder das Ergebnis etwas anderes als eine Methodengruppe ist, wird ein Fehler erzeugt; und es werden keine weiteren Schritte unternommen.- Die Auflösung von Überladungen wird für die Methodengruppe mit einer leeren Argumentliste durchgeführt. Führt die Überladungsauflösung zu keiner anwendbaren Methode, führt zu einer Mehrdeutigkeit oder führt zu einer einzigen besten Methode, aber diese Methode ist entweder statisch oder nicht öffentlich, oder der Rückgabetyp ist nicht
bool, wird ein Fehler erzeugt, und es werden keine weiteren Schritte ausgeführt.- Der Sammlungstyp ist
X, der Aufzählungstyp istE, und der Elementtyp ist der Typ derCurrent-Eigenschaft.Andernfalls wird ein Fehler erzeugt und es werden keine weiteren Schritte ausgeführt.
Für await foreach werden die Regeln entsprechend geändert. Die einzige Änderung, die für diese Spezifikation erforderlich ist, ist das Entfernen der Zeile Extension methods do not contribute. aus der Beschreibung, da der Rest dieser Spezifikation auf den oben genannten Regeln basiert, mit unterschiedlichen Namen anstelle der Mustermethoden.
Nachteile
Jede Änderung fügt der Sprache zusätzliche Komplexität hinzu, und dies könnte potenziell Dinge ermöglichen, die nicht dafür ausgelegt waren, foreach zu foreach, wie z. B. Range.
Alternativen
Nichts tun.
Ungelöste Fragen
Zu diesem Zeitpunkt nicht.
C# feature specifications