Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Tento článek je specifikace funkce. Specifikace slouží jako návrhový dokument pro funkci. Zahrnuje navrhované změny specifikace spolu s informacemi potřebnými při návrhu a vývoji funkce. Tyto články se publikují, dokud nebudou navrhované změny specifikace finalizovány a začleněny do aktuální specifikace ECMA.
Mezi specifikací funkce a dokončenou implementací může docházet k nějakým nesrovnalostem. Tyto rozdíly jsou zachyceny v příslušných poznámkách ze schůzky jazykového návrhu (LDM).
Další informace o procesu přijetí specifikací funkcí do jazyka C# najdete v článku o specifikacích .
Problém šampiona: https://github.com/dotnet/csharplang/issues/9101
Shrnutí
Umožňuje uživatelům přizpůsobit chování operátorů složeného přiřazení způsobem, který cíl přiřazení upraví na místě.
Motivation
Jazyk C# poskytuje podporu pro implementace operátoru přetížení vývojáře pro uživatelem definovaný typ.
Kromě toho poskytuje podporu pro "složené operátory přiřazení", které uživateli umožňují psát kód podobně jako x += yx = x + y. Jazyk však v současné době neumožňuje vývojáři přetížit tyto operátory složeného přiřazení a zatímco výchozí chování dělá správnou věc, zejména pokud se týká neměnných hodnotových typů, není vždy "optimální".
Vzhledem k následujícímu příkladu
class C1
{
static void Main()
{
var c1 = new C1();
c1 += 1;
System.Console.Write(c1);
}
public static C1 operator+(C1 x, int y) => new C1();
}
pomocí aktuálních pravidel jazyka operátor c1 += 1 složeného přiřazení vyvolá uživatelem definovaný + operátor a pak přiřadí jeho návratovou hodnotu k místní proměnné c1. Všimněte si, že implementace operátoru musí přidělit a vrátit novou instanci C1, zatímco z pohledu příjemce by místní změna na původní instanci C1 místo toho fungovala stejně dobře (není použita po přiřazení), s další výhodou, že se vyhnout nadbytečnému přidělení.
Když program využívá operaci složeného přiřazení, nejběžnějším účinkem je, že původní hodnota je "ztracena" a už není k dispozici pro program. U typů s velkými objemy dat (například BigInteger, Tensors atd.) jsou náklady na vytvoření čisté nové cíle, iterace a kopírování paměti poměrně nákladné. Místní varianta by umožnila vynechat tyto výdaje v mnoha případech, což může přinést významná vylepšení takových scénářů.
Proto může být přínosné pro jazyk C# umožnit uživatelům přizpůsobit chování operátorů složeného přiřazení a optimalizovat scénáře, které by jinak potřebovaly přidělit a kopírovat.
Podrobný návrh
Syntaxe
https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/classes.md#15101-general Gramatika je upravena následujícím způsobem.
Operátory jsou deklarovány pomocí operator_declarations:
operator_declaration
: attributes? operator_modifier+ operator_declarator operator_body
;
operator_modifier
: 'public'
| 'static'
| 'extern'
| unsafe_modifier // unsafe code support
| 'abstract'
| 'virtual'
| 'sealed'
+ | 'override'
+ | 'new'
+ | 'readonly'
;
operator_declarator
: unary_operator_declarator
| binary_operator_declarator
| conversion_operator_declarator
+ | increment_operator_declarator
+ | compound_assignment_operator_declarator
;
unary_operator_declarator
: type 'operator' overloadable_unary_operator '(' fixed_parameter ')'
;
logical_negation_operator
: '!'
;
overloadable_unary_operator
- : '+' | 'checked'? '-' | logical_negation_operator | '~' | 'checked'? '++' | 'checked'? '--' | 'true' | 'false'
+ : '+' | 'checked'? '-' | logical_negation_operator | '~' | 'true' | 'false'
;
binary_operator_declarator
: type 'operator' overloadable_binary_operator
'(' fixed_parameter ',' fixed_parameter ')'
;
overloadable_binary_operator
: 'checked'? '+' | 'checked'? '-' | 'checked'? '*' | 'checked'? '/' | '%' | '&' | '|' | '^' | '<<'
| right_shift | '==' | '!=' | '>' | '<' | '>=' | '<='
;
conversion_operator_declarator
: 'implicit' 'operator' type '(' fixed_parameter ')'
| 'explicit' 'operator' type '(' fixed_parameter ')'
;
+increment_operator_declarator
+ : type 'operator' overloadable_increment_operator '(' fixed_parameter ')'
+ | 'void' 'operator' overloadable_increment_operator '(' ')'
+ ;
+overloadable_increment_operator
+ : 'checked'? '++' | 'checked'? '--'
+ ;
+compound_assignment_operator_declarator
+ : 'void' 'operator' overloadable_compound_assignment_operator
+ '(' fixed_parameter ')'
+ ;
+overloadable_compound_assignment_operator
+ : 'checked'? '+=' | 'checked'? '-=' | 'checked'? '*=' | 'checked'? '/=' | '%=' | '&=' | '|=' | '^=' | '<<='
+ | right_shift_assignment
+ | unsigned_right_shift_assignment
+ ;
operator_body
: block
| '=>' expression ';'
| ';'
;
Existuje pět kategorií přetížitelných operátorů: unární operátory, binární operátory, operátory převodu, operátory přírůstku, složené operátory přiřazení.
Následující pravidla platí pro všechny deklarace operátorů:
- Prohlášení operátoru
publiczahrnujestaticmodifikátor, tak i modifikátor.
Složené operátory přiřazení a inkrementace instancí mohou skrýt operátory deklarované v základní třídě. Proto následující odstavec již není přesný a měl by být odpovídajícím způsobem upraven nebo lze jej odebrat:
Vzhledem k tomu, že deklarace operátorů vždy vyžadují třídu nebo strukturu, ve které je operátor deklarován pro účast v podpisu operátoru, není možné, aby operátor deklarovaný v odvozené třídě skryl operátor deklarovaný v základní třídě.
newModifikátor se tedy nikdy nevyžaduje, a proto není nikdy povolen v deklaraci operátoru.
Unární operátory
Viz https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/classes.md#15102-unary-operators.
Prohlášení operátoru static musí obsahovat modifikátor a nesmí obsahovat override modifikátor.
Následující odrážka se odebere:
- Unární
++nebo--operátor přijme jeden parametr typuTneboT?vrátí stejný typ nebo typ odvozený z něj.
Následující odstavec se upraví tak, aby již nezmínil tokeny operátoru a ++ nezmínil--:
Podpis unárního operátoru se skládá z tokenu operátoru (
+,-!,~,++,--, ,true, nebofalse) a typu jednoho parametru. Návratový typ není součástí podpisu unárního operátoru ani není název parametru.
Příklad v oddílu by se měl upravit tak, aby nepoužíval uživatelem definovaný operátor přírůstku.
Binární operátory
Viz https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/classes.md#15103-binary-operators.
Prohlášení operátoru static musí obsahovat modifikátor a nesmí obsahovat override modifikátor.
Operátory převodu
Prohlášení operátoru static musí obsahovat modifikátor a nesmí obsahovat override modifikátor.
Operátory přírůstku
Následující pravidla platí pro deklarace statického operátoru přírůstku, kde T označuje typ instance třídy nebo struktury, která obsahuje deklaraci operátoru:
- Prohlášení operátoru
staticmusí obsahovat modifikátor a nesmí obsahovatoverridemodifikátor. - Provozovatel převezme jeden parametr typu
TneboT?vrátí stejný typ nebo typ odvozený z něj.
Podpis statického operátoru přírůstku se skládá z tokenů operátoru ('checked'? ++, 'checked'? --) a typu jednoho parametru.
Návratový typ není součástí podpisu statického operátoru přírůstku ani název parametru.
Statické operátory přírůstku jsou velmi podobné unárním operátorům.
Následující pravidla platí pro deklarace operátoru přírůstku instance:
- Deklarace operátoru
staticnesmí obsahovat modifikátor. - Provozovatel nepřebírají žádné parametry.
- Operátor musí mít
voidnávratový typ.
Operátor inkrementace instance je void návratové metody instance, která nemá žádné parametry a má speciální název v metadatech.
Podpis operátoru přírůstku instance se skládá z tokenů operátoru ("zaškrtnuto"? '++' | "Zaškrtnuto"? '--').
Deklarace checked operator vyžaduje párově moudrou regular operatordeklaraci . V opačném případě dojde k chybě kompilace.
Viz také .. /csharp-11.0/checked-user-defined-operators.md#sémantics.
Účelem metody je upravit hodnotu instance na výsledek požadované operace přírůstku, ať už to znamená v kontextu deklarujícího typu.
Příklad:
class C1
{
public int Value;
public void operator ++()
{
Value++;
}
}
Operátor inkrementace instance může přepsat operátor se stejným podpisem deklarovaným v základní třídě, override modifikátor lze použít pro tento účel.
Do ECMA-335 by se měly přidat následující speciální názvy "reserved", aby podporovaly verze instancí operátorů přírůstku/dekrementace: | Název | Operátor | | -----| -------- | |op_DecrementAssignment| -- | |op_IncrementAssignment| ++ | |op_CheckedDecrementAssignment| zaškrtnuto -- | |op_CheckedIncrementAssignment| zaškrtnuto ++ |
Operátory složeného přiřazení
Následující pravidla platí pro deklarace operátoru složeného přiřazení:
- Deklarace operátoru
staticnesmí obsahovat modifikátor. - Operátor převezme jeden parametr.
- Operátor musí mít
voidnávratový typ.
Operátor složeného přiřazení je void vracející metodu instance, která přebírá jeden parametr a má zvláštní název v metadatech.
Podpis operátoru složeného přiřazení se skládá z tokenů operátoru ("zaškrtnuto"? "+=", "zaškrtnuto"? '-=', 'zaškrtnuto'? '*=', 'checked'? '/=', '%=', '&=', '|=', '^=', '<<=', right_shift_assignment, unsigned_right_shift_assignment) a typ jednoho parametru. Název parametru není součástí podpisu operátoru složeného přiřazení.
Deklarace checked operator vyžaduje párově moudrou regular operatordeklaraci . V opačném případě dojde k chybě kompilace.
Viz také .. /csharp-11.0/checked-user-defined-operators.md#sémantics.
Účelem metody je upravit hodnotu instance na výsledek <instance> <binary operator token> parameter.
Příklad:
class C1
{
public int Value;
public void operator +=(int x)
{
Value+=x;
}
}
Operátor složeného přiřazení může přepsat operátor se stejným podpisem deklarovaným v základní třídě, override modifikátor lze použít pro tento účel.
ECMA-335 již "rezervováno" následující speciální názvy pro uživatelem definované operátory přírůstku: | Název | Operátor | | -----| -------- | |op_AdditionAssignment| +=' | |op_SubtractionAssignment|' -=' | |op_MultiplicationAssignment|' *=' | |op_DivisionAssignment|' /=' | |op_ModulusAssignment|'%=' | |op_BitwiseAndAssignment|' &=' | |op_BitwiseOrAssignment|'|=' | |op_ExclusiveOrAssignment|' ^=' | |op_LeftShiftAssignment|<<='| |op_RightShiftAssignment| right_shift_assignment| |op_UnsignedRightShiftAssignment|unsigned_right_shift_assignment|
Uvádí však, že dodržování předpisů CLS vyžaduje, aby metody operátoru byly statické metody bez void se dvěma parametry, tj. odpovídá tomu, co jsou binární operátory jazyka C#. Měli bychom zvážit uvolnění požadavků na dodržování předpisů CLS, aby operátory mohly být neplatné návratové metody instance s jedním parametrem.
Pro podporu kontrolovaných verzí operátorů by se měly přidat následující názvy: | Název | Operátor | | -----| -------- | |op_CheckedAdditionAssignment| zaškrtnuto '+=' | |op_CheckedSubtractionAssignment| zaškrtnuto '-=' | |op_CheckedMultiplicationAssignment| zaškrtnuto '*=' | |op_CheckedDivisionAssignment| zaškrtnuto '/=' |
Operátory inkrementace a dekrementace předpony
Pokud x je in «op» x klasifikovaná jako proměnná a cílí na novou jazykovou verzi, pak se priorita přiřadí operátorům inkrementace instancí následujícím způsobem.
Nejprve je proveden pokus o zpracování operace použitím operátoru zvýšení instance přetížení. Pokud proces nevygeneruje žádný výsledek a žádná chyba, operace se zpracuje použitím rozlišení přetížení unárního operátoru, jak https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#1296-prefix-increment-and-decrement-operators je aktuálně uvedeno.
V opačném případě se operace «op»x vyhodnotí následujícím způsobem.
Pokud je známo, že typ x odkazu, je vyhodnocen získat x instanci x₀, operátor metoda je vyvolána na této instanci a x₀ je vrácena v důsledku operace.
Pokud x₀ je null, vyvolání metody operátoru vyvolá nullReferenceException.
Například:
var a = ++(new C()); // error: not a variable
var b = ++a; // var temp = a; temp.op_Increment(); b = temp;
++b; // b.op_Increment();
var d = ++C.P1; // error: setter is missing
++C.P1; // error: setter is missing
var e = ++C.P2; // var temp = C.op_Increment(C.get_P2()); C.set_P2(temp); e = temp;
++C.P2; // var temp = C.op_Increment(C.get_P2()); C.set_P2(temp);
class C
{
public static C P1 { get; } = new C();
public static C P2 { get; set; } = new C();
public static C operator ++(C x) => ...;
public void operator ++() => ...;
}
Pokud typ x není znám jako odkazový typ:
- Pokud se použije výsledek přírůstku,
xvyhodnotí se získat instancix₀, operátor metoda je vyvolána na této instanci,x₀je přiřazenaxax₀je vrácena v důsledku složeného přiřazení. - V opačném případě je operátor metoda vyvolána .
x
Všimněte si, že vedlejší účinky jsou x vyhodnoceny pouze jednou v procesu.
Například:
var a = ++(new S()); // error: not a variable
var b = ++S.P2; // var temp = S.op_Increment(S.get_P2()); S.set_P2(temp); b = temp;
++S.P2; // var temp = S.op_Increment(S.get_P2()); S.set_P2(temp);
++b; // b.op_Increment();
var d = ++S.P1; // error: set is missing
++S.P1; // error: set is missing
var e = ++b; // var temp = b; temp.op_Increment(); e = (b = temp);
struct S
{
public static S P1 { get; } = new S();
public static S P2 { get; set; } = new S();
public static S operator ++(S x) => ...;
public void operator ++() => ...;
}
Operátory přírůstku a dekrementace přípony
Pokud je výsledek operace použit nebo x není x «op» klasifikován jako proměnná nebo je cílem staré jazykové verze, operace se zpracuje použitím rozlišení přetížení unárního operátoru, jak https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#12816-postfix-increment-and-decrement-operators je aktuálně uvedeno.
Důvodem, proč se při použití výsledku ani nepokoušíme operátory inkrementace instance, je skutečnost, že pokud pracujeme s odkazovým typem, není možné vytvořit hodnotu x před operací, pokud je používaná ztlumená.
Pokud pracujeme s typem hodnoty, budeme muset přesto vytvořit kopie atd.
V opačném případě se priorita udělí operátorům inkrementace instancí následujícím způsobem.
Nejprve je proveden pokus o zpracování operace použitím operátoru zvýšení instance přetížení. Pokud proces nevygeneruje žádný výsledek a žádná chyba, operace se zpracuje použitím rozlišení přetížení unárního operátoru, jak https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#12816-postfix-increment-and-decrement-operators je aktuálně uvedeno.
V opačném případě se operace x«op» vyhodnotí následujícím způsobem.
Je-li typ x známé jako referenční typ, je vyvolána metoda operátoru x.
Pokud x je null, vyvolání metody operátoru vyvolá nullReferenceException.
Například:
var a = (new C())++; // error: not a variable
var b = new C();
var c = b++; // var temp = b; b = C.op_Increment(temp); c = temp;
b++; // b.op_Increment();
var d = C.P1++; // error: missing setter
C.P1++; // error: missing setter
var e = C.P2++; // var temp = C.get_P2(); C.set_P2(C.op_Increment(temp)); e = temp;
C.P2++; // var temp = C.get_P2(); C.set_P2(C.op_Increment(temp));
class C
{
public static C P1 { get; } = new C();
public static C P2 { get; set; } = new C();
public static C operator ++(C x) => ...;
public void operator ++() => ...;
}
Pokud typ x není znám jako referenční typ, je vyvolána metoda operátoru x.
Například:
var a = (new S())++; // error: not a variable
var b = S.P2++; // var temp = S.get_P2(); S.set_P2(S.op_Increment(temp)); b = temp;
S.P2++; // var temp = S.get_P2(); S.set_P2(S.op_Increment(temp));
b++; // b.op_Increment();
var d = S.P1++; // error: set is missing
S.P1++; // error: missing setter
var e = b++; // var temp = b; b = S.op_Increment(temp); e = temp;
struct S
{
public static S P1 { get; } = new S();
public static S P2 { get; set; } = new S();
public static S operator ++(S x) => ...;
public void operator ++() => ...;
}
Rozlišení přetížení operátoru inkrementace instance
Operace formuláře «op» x nebo x «op», kde «op» je přetížitelný inkrementovací operátor, a x je výraz typu X, je zpracován takto:
- Sada kandidátských uživatelem definovaných operátorů poskytovaných
Xpro operacioperator «op»(x)je určena pomocí pravidel inkrementace instancí kandidáta. - Pokud sada kandidátských uživatelem definovaných operátorů není prázdná, stane se tím sada kandidátských operátorů pro operaci. V opačném případě rozlišení přetížení nepřináší žádný výsledek.
- Pravidla rozlišení přetížení se použijí na sadu kandidátských operátorů pro výběr nejlepšího operátoru a tento operátor se stane výsledkem procesu řešení přetížení. Pokud se řešení přetížení nepodaří vybrat jeden nejlepší operátor, dojde k chybě doby vazby.
Operátory přírůstku instance kandidáta
Za předpokladu typu T a operace «op», kde «op» je přetížitelný operátor inkrementace instance, je sada kandidátských uživatelem definovaných operátorů T určena následujícím způsobem:
- V
uncheckedkontextu vyhodnocení se jedná o skupinu operátorů, které by byly vytvořeny vyhledávacím procesem člena, pokud byly považovány pouze za operátory instanceoperator «op»(), které odpovídají cílovému názvuN. - V
checkedkontextu vyhodnocení se jedná o skupinu operátorů, které by byly vytvořeny vyhledávacím procesem člena, pokud by byly považovány pouze za instance a operátory instancíoperator «op»()operator checked «op»(), které odpovídají cílovému názvuN. Operátoryoperator «op»(), které mají deklarace párového párováníoperator checked «op»(), jsou ze skupiny vyloučeny.
Složené přiřazení
Odstavec na začátku, který se zabývá dynamic , je stále použitelný tak, jak je.
Jinak platí, že pokud x je in x «op»= y klasifikovaný jako proměnná a cílí na novou jazykovou verzi, pak se priorita přiřadí operátorům složeného přiřazení následujícím způsobem.
Nejprve se pokusí zpracovat operaci formuláře x «op»= y použitím rozlišení přetížení operátoru složeného přiřazení.
Pokud proces nevygeneruje žádný výsledek a žádná chyba, operace se zpracuje použitím rozlišení přetížení binárního operátoru, jak https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#12214-compound-assignment je aktuálně uvedeno.
V opačném případě se operace vyhodnotí následujícím způsobem.
Pokud je typ x známé jako typ odkazu, je vyhodnocen k x získání instance x₀, operátor metoda je vyvolána na této instanci s argumentem y a x₀ je vrácena v důsledku složeného přiřazení.
Pokud x₀ je null, vyvolání metody operátoru vyvolá nullReferenceException.
Například:
var a = (new C())+=10; // error: not a variable
var b = a += 100; // var temp = a; temp.op_AdditionAssignment(100); b = temp;
var c = b + 1000; // c = C.op_Addition(b, 1000)
c += 5; // c.op_AdditionAssignment(5);
var d = C.P1 += 11; // error: setter is missing
var e = C.P2 += 12; // var temp = C.op_Addition(C.get_P2(), 12); C.set_P2(temp); e = temp;
C.P2 += 13; // var temp = C.op_Addition(C.get_P2(), 13); C.set_P2(temp);
class C
{
public static C P1 { get; } = new C();
public static C P2 { get; set; } = new C();
// op_Addition
public static C operator +(C x, int y) => ...;
// op_AdditionAssignment
public void operator +=(int y) => ...;
}
Pokud typ x není znám jako odkazový typ:
- Pokud se použije výsledek složeného přiřazení,
xvyhodnotí se pro získání instancex₀, operátor metoda je vyvolána na této instanci s argumentemy,x₀je přiřazenaxax₀je vrácena v důsledku složeného přiřazení. - V opačném případě je metoda operátoru vyvolána
xjakoyargument.
Všimněte si, že vedlejší účinky jsou x vyhodnoceny pouze jednou v procesu.
Například:
var a = (new S())+=10; // error: not a variable
var b = S.P2 += 100; // var temp = S.op_Addition(S.get_P2(), 100); S.set_P2(temp); b = temp;
S.P2 += 100; // var temp = S.op_Addition(S.get_P2(), 100); S.set_P2(temp);
var c = b + 1000; // c = S.op_Addition(b, 1000)
c += 5; // c.op_AdditionAssignment(5);
var d = S.P1 += 11; // error: setter is missing
var e = c += 12; // var temp = c; temp.op_AdditionAssignment(12); e = (c = temp);
struct S
{
public static S P1 { get; } = new S();
public static S P2 { get; set; } = new S();
// op_Addition
public static S operator +(S x, int y) => ...;
// op_AdditionAssignment
public void operator +=(int y) => ...;
}
Rozlišení přetížení operátoru složeného přiřazení
Operace formuláře x «op»= y, kde «op»= je přetížitelný složený operátor přiřazení, x je výraz typu X je zpracován takto:
- Sada kandidátských uživatelem definovaných operátorů poskytovaných
Xpro operacioperator «op»=(y)je určena pomocí pravidel kandidátských operátorů složeného přiřazení. - Pokud je pro seznam
(y)argumentů použitelný alespoň jeden kandidáta uživatelem definovaný operátor v sadě , stane se sada kandidátských operátorů pro operaci. V opačném případě rozlišení přetížení nepřináší žádný výsledek. - Pravidla rozlišení přetížení se použijí na sadu kandidátských operátorů, aby vybrali nejlepší operátor s ohledem na seznam
(y)argumentů a tento operátor se stane výsledkem procesu řešení přetížení. Pokud se řešení přetížení nepodaří vybrat jeden nejlepší operátor, dojde k chybě doby vazby.
Operátory složeného přiřazení kandidáta
Při zadání typu T a operace «op»=, kde «op»= je přetížitelný operátor složeného přiřazení, je sada kandidátských uživatelem definovaných operátorů T určena následujícím způsobem:
- V
uncheckedkontextu vyhodnocení se jedná o skupinu operátorů, které by byly vytvořeny vyhledávacím procesem člena, pokud byly považovány pouze za operátory instanceoperator «op»=(Y), které odpovídají cílovému názvuN. - V
checkedkontextu vyhodnocení se jedná o skupinu operátorů, které by byly vytvořeny vyhledávacím procesem člena, pokud by byly považovány pouze za instance a operátory instancíoperator «op»=(Y)operator checked «op»=(Y), které odpovídají cílovému názvuN. Operátoryoperator «op»=(Y), které mají deklarace párového párováníoperator checked «op»=(Y), jsou ze skupiny vyloučeny.
Otevřené otázky
[Vyřešeno] Má readonly být modifikátor povolen ve strukturách?
Zdá se, že neexistuje žádná výhoda, protože by bylo možné označit metodu, když readonly celý účel metody je upravit instanci.
Závěr: Modifikátory povolíme readonly , ale v tuto chvíli neuvolníme cílové požadavky.
[Vyřešeno] Má být povolené stínování?
Pokud odvozená třída deklaruje operátor inkrementace "složené přiřazení"/"instance se stejným podpisem jako v základu, měli bychom vyžadovat override modifikátor?
Závěr: Stínování bude povoleno se stejnými pravidly jako metody.
[Vyřešeno] Měli bychom mít zajištění konzistentnosti mezi deklarovanými operátory += a +?
Během LDM-2025-02-12 byla vyjádřena obava, že autoři svými omyly zatlačí své uživatele do nestandardních scénářů, kdy += může fungovat, ale + nebude (nebo naopak), protože jedna forma deklaruje více operátorů než druhá.
Závěr: Kontroly ohledně konzistence nebudou prováděny u různých typů operátorů.
Alternatives
Použití statických metod
Mohli bychom zvážit použití statických operátorů metod, kdy se instance, která má být ztlumená, předána jako první parametr. V případě typu hodnoty musí být tento parametr parametrem ref .
Jinak metoda nebude moct ztlumit cílovou proměnnou. Současně by tento parametr neměl být parametrem ref v případě typu třídy. Protože v případě třídy musí být předaný v instanci mutován, nikoli umístění, kde je instance uložena. Pokud je však operátor deklarován v rozhraní, není často známo, zda bude rozhraní implementováno pouze třídami, nebo pouze strukturami. Proto není jasné, zda má být prvním parametrem ref parametr.
Designérské schůzky
C# feature specifications