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ě.
Motivace
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 += y
x = 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
public
zahrnujestatic
modifiká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ě.
new
Modifiká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 typuT
neboT?
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
static
musí obsahovat modifikátor a nesmí obsahovatoverride
modifikátor. - Provozovatel převezme jeden parametr typu
T
neboT?
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
static
nesmí obsahovat modifikátor. - Provozovatel nepřebírají žádné parametry.
- Operátor musí mít
void
ná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 operator
deklaraci . V opačném případě dojde k chybě kompilace.
Viz také https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/checked-user-defined-operators.md#semantics.
Úč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
static
nesmí obsahovat modifikátor. - Operátor převezme jeden parametr.
- Operátor musí mít
void
ná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 operator
deklaraci . V opačném případě dojde k chybě kompilace.
Viz také https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/checked-user-defined-operators.md#semantics.
Úč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,
x
vyhodnotí se získat instancix₀
, operátor metoda je vyvolána na této instanci,x₀
je přiřazenax
ax₀
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
X
pro 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
unchecked
kontextu 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
checked
kontextu 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í,
x
vyhodnotí se pro získání instancex₀
, operátor metoda je vyvolána na této instanci s argumentemy
,x₀
je přiřazenax
ax₀
je vrácena v důsledku složeného přiřazení. - V opačném případě je metoda operátoru vyvolána
x
jakoy
argument.
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
X
pro 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
unchecked
kontextu 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
checked
kontextu 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ů.
Alternativy
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