Krav för avkopplande skiftoperator
Anteckning
Den här artikeln är en funktionsspecifikation. Specifikationen fungerar som designdokument för funktionen. Den innehåller föreslagna specifikationsändringar, tillsammans med information som behövs under utformningen och utvecklingen av funktionen. Dessa artiklar publiceras tills de föreslagna specifikationsändringarna har slutförts och införlivats i den aktuella ECMA-specifikationen.
Det kan finnas vissa skillnader mellan funktionsspecifikationen och den slutförda implementeringen. De där skillnaderna fångas upp i de relevanta anteckningarna från språkdesignmöte (LDM, Language Design Meeting).
Du kan läsa mer om processen för att införa funktionsspecifikationer i C#-språkstandarden i artikeln om specifikationerna.
Champion-problem: https://github.com/dotnet/csharplang/issues/4666
Sammanfattning
Skiftoperatorns krav kommer att lättas så att operanden på högra sidan inte längre är begränsad till att bara vara int
.
Motivation
När du arbetar med andra typer än int
är det inte ovanligt att du skiftar med hjälp av resultatet av en annan beräkning, till exempel växling baserat på leading zero count
. Den naturliga typen av något som liknar en leading zero count
är samma som indatatypen (TSelf
) och i många fall kräver detta att du konverterar resultatet till int
innan du flyttar, även om det resultatet redan ligger inom intervallet.
Inom ramen för de allmänna matematiska gränssnitt som biblioteken planerar att exponera är detta potentiellt problematiskt eftersom typen inte är välkänd och därför kanske konverteringen till int
inte är möjlig eller ens väldefinierad.
Detaljerad design
Skiftoperatorer
§12.11 omformuleras på följande sätt:
- 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.
Det innebär att begränsningen att den första operanden är klassen eller structen som innehåller operatordeklarationen finns kvar.
Begränsningen att den andra operanden måste vara int
tas bort.
Binära operatorer
§14.10.3 omformuleras på följande sätt:
-* 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.
Det vill säga att begränsningen att den första parametern ska vara T
eller T?
kvarstår.
Den begränsning som den andra operanden måste vara int
eller int?
tas bort.
Överbelastningsupplösning för binär operator
Den första punktpunkten på §11.4.5 bör omformuleras på följande sätt:
- Uppsättningen med användardefinierade operatorer som tillhandahålls av
X
ochY
för operationenoperator op(x,y)
bestäms. Uppsättningen består av en union av de kandidatoperatorer som tillhandahålls avX
och , såvida inte operatören är en skiftoperatör, de kandidatoperatörer som tillhandahålls avY
, var och en bestäms med hjälp av reglerna för kandidatanvändardefinierade operatörer §11.4.6. OmX
ochY
är av samma typ, eller omX
ochY
härleds från en gemensam bastyp, uppstår endast delade kandidatoperatorer i den kombinerade uppsättningen en gång.
För skiftoperatorer är det alltså bara kandidatoperatorer som tillhandahålls av typen X
.
Nackdelar
Användare kan definiera operatorer som inte följer de rekommenderade riktlinjerna, till exempel implementering av cout << "string"
i C#.
Alternativ
De allmänna matematiska gränssnitt som exponeras av biblioteken kan exponera explicit namngivna metoder i stället. Detta kan göra koden svårare att läsa/underhålla.
De allmänna matematiska gränssnitten kan kräva att skiftet tar int
och att en konvertering utförs.
Den här konverteringen kan vara dyr eller kanske inte är möjlig beroende på vilken typ det gäller.
Olösta frågor
Finns det en oro för att bevara "avsikten" kring varför den andra operanden begränsades till int
?
Designa möten
https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md
C# feature specifications