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 int
beschränkt ist.
Motivation
Wenn Sie mit anderen Typen als int
arbeiten, 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
undY
bereitgestellte Satz benutzerdefinierter Kandidatenoperatoren für den Vorgangoperator op(x,y)
ist bestimmt. Die Gruppe besteht aus der Vereinigung der vonX
und bereitgestellten Kandidatenoperatoren, es sei denn, der Operator ist ein Verschiebungsoperator, der vonY
bereitgestellt wird, jeweils bestimmt durch die Verwendung der Regeln für benutzerdefinierte Kandidatenoperatoren in §11.4.6. WennX
undY
denselben Typ aufweisen oderX
undY
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 X
bereitgestellt 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
C# feature specifications