Freigeben über


Vereinfachung der Anforderungen an Verschiebungsoperatoren

Anmerkung

Dieser Artikel ist eine Featurespezifikation. 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 Featurespezifikation und der abgeschlossenen Implementierung geben. Diese Unterschiede werden in den relevanten Anmerkungen 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.

Zusammenfassung

Die Anforderungen an den Verschiebungsoperator werden vereinfacht, sodass der rechte Operand nicht mehr auf intbeschränkt ist.

Motivation

Wenn Sie mit anderen Typen als intarbeiten, ist es nicht ungewöhnlich, dass Sie eine Verschiebung basierend auf dem Ergebnis eines anderen Berechnungsergebnisses durchführen, beispielsweise eine Verschiebung basierend auf leading zero count. Der natürliche Typ von etwas wie leading zero count ist identisch mit dem Eingabetyp (TSelf). Daher erfordert dies in vielen Fällen die Umwandlung dieses Ergebnisses in int vor der Verschiebung, auch wenn dieses Ergebnis bereits im Bereich liegt.

Im Kontext der generischen mathematischen Schnittstellen, die die Bibliotheken bereitstellen möchten, ist dies potenziell problematisch, da der Typ nicht gut bekannt ist und die Konvertierung in int möglicherweise nicht möglich oder nicht einmal eindeutig definiert ist.

Detailliertes Design

Schiebeoperatoren

§12.11 sollte wie folgt umgeschrieben werden:

- When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration,
and the type of the second operand must always be int.
+ When declaring an overloaded shift operator, the type of the first operand must always be the class or struct containing the operator declaration.

Das heißt, die Einschränkung, dass der erste Operand die Klasse oder Struktur ist, die die Operatordeklaration enthält, bleibt erhalten. Die Einschränkung, dass der zweite Operand int sein muss, wird aufgehoben.

Binäre Operatoren

§14.10.3 sollte wie folgt umgeschrieben werden:

-*  A binary `<<` or `>>` operator must take two parameters, the first of which must have type `T` or `T?` and the second of which must have type `int` or `int?`, and can return any type.
+*  A binary `<<` or `>>` operator must take two parameters, the first of which must have type `T` or `T?`, and can return any type.

Das heißt, die Einschränkung, dass der erste Parameter T oder T? sein muss, bleibt bestehen. Die Einschränkung, dass der zweite Operand int oder int? sein muss, wird entfernt.

Lösung für die Überladung binärer Operatoren

Der erste Aufzählungspunkt unter §11.4.5 sollte wie folgt umformuliert werden:

  • Der von X und Y bereitgestellte Satz benutzerdefinierter Kandidatenoperatoren für den Vorgang operator op(x,y) ist bestimmt. Die Gruppe besteht aus der Vereinigung der von X und bereitgestellten Kandidatenoperatoren, es sei denn, der Operator ist ein Verschiebungsoperator, der von Y bereitgestellt wird, jeweils bestimmt durch die Verwendung der Regeln für benutzerdefinierte Kandidatenoperatoren in §11.4.6. Wenn X und Y denselben Typ aufweisen oder X und Y von einem gemeinsamen Basistyp abgeleitet werden, treten freigegebene Kandidatenoperatoren nur einmal im kombinierten Satz auf.

Das bedeutet, dass die Kandidatenoperatoren für Verschiebungsoperatoren nur vom Typ Xbereitgestellt werden.

Nachteile

Benutzer können Operatoren definieren, die nicht den empfohlenen Richtlinien entsprechen, z. B. das Implementieren von cout << "string" in C#.

Alternativen

Die generischen mathematischen Schnittstellen, die von den Bibliotheken verfügbar gemacht werden, könnten stattdessen explizit benannte Methoden verfügbar machen. Dies kann das Lesen/Verwalten von Code erschweren.

Die generischen mathematischen Schnittstellen könnten erfordern, dass die Verschiebung int nimmt und eine Umwandlung durchgeführt wird. Diese Konvertierung kann teuer oder je nach betreffenden Typ nicht möglich sein.

Ungelöste Fragen

Gibt es Bedenken hinsichtlich der Beibehaltung der „Absicht“, warum der zweite Operand auf int beschränkt war?

Entwurfsbesprechungen

https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md