Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Nota
Artikel ini adalah spesifikasi fitur. Spesifikasi berfungsi sebagai dokumen desain untuk fitur tersebut. Ini termasuk perubahan spesifikasi yang diusulkan, bersama dengan informasi yang diperlukan selama desain dan pengembangan fitur. Artikel ini diterbitkan sampai perubahan spesifikasi yang diusulkan diselesaikan dan dimasukkan dalam spesifikasi ECMA saat ini.
Mungkin ada beberapa perbedaan antara spesifikasi fitur dan implementasi yang selesai. Perbedaan tersebut tertuangkan dalam catatan rapat terkait desain bahasa (LDM) .
Anda dapat mempelajari lebih lanjut tentang proses untuk mengadopsi speklet fitur ke dalam standar bahasa C# dalam artikel tentang spesifikasi .
Edisi unggulan: https://github.com/dotnet/csharplang/issues/9101
Ringkasan
Izinkan jenis pengguna untuk menyesuaikan perilaku operator penugasan gabungan dengan cara agar target penugasan dimodifikasi di tempat.
Motivasi
C# menyediakan dukungan bagi developer untuk mengimplementasikan operator overloading pada tipe yang ditentukan pengguna.
Selain itu, ini menyediakan dukungan untuk "operator penugasan majemuk" yang memungkinkan pengguna untuk menulis kode seperti x += y
daripada x = x + y
. Namun, bahasa saat ini tidak memungkinkan pengembang untuk membebani operator penugasan majemuk ini dan sementara perilaku default melakukan hal yang benar, terutama karena berkaitan dengan jenis nilai yang tidak dapat diubah, itu tidak selalu "optimal".
Berikut ini adalah contohnya
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();
}
dengan aturan bahasa saat ini, operator c1 += 1
penugasan gabungan memanggil operator yang ditentukan +
pengguna dan kemudian menetapkan nilai pengembaliannya ke variabel c1
lokal . Perhatikan bahwa implementasi operator harus mengalokasikan dan mengembalikan instans baru C1
, sedangkan dari perspektif konsumen, perubahan di tempat pada instans C1
asli akan sama baiknya (tidak digunakan setelah penugasan), dengan manfaat tambahan untuk menghindari alokasi tambahan.
Ketika program menggunakan operasi penugasan gabungan, efek yang paling umum adalah nilai asli "hilang" dan tidak lagi tersedia bagi program. Dengan tipe dengan data yang besar (seperti BigInteger, Tensors, dll.) biaya untuk membuat tujuan baru yang sepenuhnya baru, melakukan iterasi, dan menyalin memori cenderung sangat mahal. Mutasi di tempat akan memungkinkan melewatkan pengeluaran ini dalam banyak kasus, yang dapat memberikan peningkatan signifikan pada skenario tersebut.
Oleh karena itu, mungkin bermanfaat bagi C# untuk memungkinkan tipe pengguna menyesuaikan perilaku operator penugasan gabungan dan mengoptimalkan skenario yang sebaliknya harus mengalokasikan dan menyalin.
Desain terperinci
Sintaksis
Tata bahasa di https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/classes.md#15101-general disesuaikan sebagai berikut.
Operator dinyatakan menggunakan operator_declaration:
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 ';'
| ';'
;
Ada lima kategori operator yang dapat kelebihan beban: operator unary, operator biner, operator konversi, operator inkrement, operator penugasan majemuk.
Aturan berikut berlaku untuk semua deklarasi operator:
- Deklarasi operator
harus mencakup danpublic
pengubah.static
Operator penugasan majemuk dan peningkatan instance dapat menyembunyikan operator yang dideklarasikan dalam kelas dasar. Oleh karena itu, paragraf berikut tidak lagi akurat dan harus disesuaikan dengan sesuai, atau dapat dihapus:
Karena deklarasi operator selalu mengharuskan kelas atau struct tempat operator dinyatakan terlibat dalam tandatangan operator, maka operator yang dideklarasikan dalam kelas turunan tidak dapat menyembunyikan operator yang dideklarasikan dalam kelas dasar. Dengan demikian, pengubah
new
tidak pernah diperlukan, dan oleh karena itu tidak pernah diizinkan, dalam deklarasi operator.
Operator Tunggal
Lihat https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/classes.md#15102-unary-operators.
Deklarasi operator harus mencakup pengubah static
dan tidak boleh menyertakan pengubah override
.
Poin peluru berikut dihapus:
- Unary
++
atau--
operator harus mengambil satu parameter dari jenisT
atauT?
dan harus mengembalikan jenis yang sama atau jenis yang diturunkan darinya.
Paragraf berikut disesuaikan dengan tidak lagi menyebutkan ++
dan --
token operator:
Tanda tangan operator unary terdiri dari token operator (
+
, ,-
,!
,~
++
,--
,true
, ataufalse
) dan jenis parameter tunggal. Jenis pengembalian bukan bagian dari tanda tangan operator unary, juga bukan nama parameter.
Contoh dalam bagian ini harus disesuaikan agar tidak menggunakan operator peningkatan yang ditentukan pengguna.
Operator biner
Lihat https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/classes.md#15103-binary-operators.
Deklarasi operator harus mencakup pengubah static
dan tidak boleh menyertakan pengubah override
.
Operator konversi
Deklarasi operator harus mencakup pengubah static
dan tidak boleh menyertakan pengubah override
.
Operator peningkatan
Aturan berikut berlaku untuk deklarasi operator kenaikan statis, di mana T
menunjukkan jenis instans kelas atau struktur yang berisi deklarasi operator:
- Deklarasi operator harus mencakup pengubah
static
dan tidak boleh menyertakan pengubahoverride
. - Operator harus mengambil satu parameter jenis
T
atauT?
dan harus mengembalikan jenis yang sama atau jenis yang diturunkan darinya.
Tanda tangan operator kenaikan statis terdiri dari token operator ('diperiksa'? ++
, 'diperiksa'? --
) dan jenis parameter tunggal.
Jenis pengembalian bukan bagian dari tanda tangan operator kenaikan statis, juga bukan nama parameter.
Operator kenaikan statis sangat mirip dengan operator unary.
Aturan berikut berlaku untuk deklarasi operator penambahan turunan:
- Deklarasi operator tidak boleh menyertakan pengubah
static
. - Operator tidak boleh mengambil parameter.
- Operator harus memiliki
void
jenis pengembalian.
Secara efektif, operator penambahan instans adalah metode instans yang mengembalikan void, tidak memiliki parameter, dan memiliki nama khusus dalam metadata.
Tanda tangan dari operator penambahan instans terdiri dari token operator, yaitu ('checked'? '++' | 'checked'? '--').
checked operator
Deklarasi membutuhkan deklarasi berpasangan dari regular operator
. Jika tidak, akan terjadi kesalahan waktu kompilasi.
Lihat juga https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/checked-user-defined-operators.md#semantics.
Tujuan dari metode ini adalah untuk menyesuaikan nilai instans dengan hasil operasi kenaikan yang diminta, apa pun artinya dalam konteks jenis deklarasikan.
Contoh:
class C1
{
public int Value;
public void operator ++()
{
Value++;
}
}
Operator kenaikan instans dapat mengambil alih operator dengan tanda tangan yang sama yang dideklarasikan dalam kelas dasar, pengubah override
dapat digunakan untuk tujuan ini.
Nama khusus "yang dicadangkan" berikut harus ditambahkan ke ECMA-335 untuk mendukung versi instans dari operator peningkatan/penurunan: | Nama | Operator | | -----| -------- | |op_DecrementAssignment| --
| |op_IncrementAssignment| ++
| |op_CheckedDecrementAssignment| pengecekan --
| |op_CheckedIncrementAssignment| pengecekan ++
|
Operator penugasan gabungan
Aturan berikut berlaku untuk deklarasi operator penugasan majemuk:
- Deklarasi operator tidak boleh menyertakan pengubah
static
. - Operator harus mengambil satu parameter.
- Operator harus memiliki
void
jenis pengembalian.
Secara efektif, operator penugasan gabungan adalah metode instans yang mengembalikan void, yang mengambil satu parameter dan memiliki nama khusus dalam metadata.
Tanda tangan operator penugasan gabungan terdiri dari token operator ('diperiksa'? '+=', 'diperiksa'? '-=', 'diperiksa'? '*=', 'diperiksa'? '/=', '%=', '&=', '|=', '^=', '<<=', right_shift_assignment, unsigned_right_shift_assignment) dan tipe parameter tunggal. Nama parameter bukan bagian dari tanda tangan operator penugasan gabungan.
checked operator
Deklarasi membutuhkan deklarasi berpasangan dari regular operator
. Jika tidak, akan terjadi kesalahan waktu kompilasi.
Lihat juga https://github.com/dotnet/csharplang/blob/main/proposals/csharp-11.0/checked-user-defined-operators.md#semantics.
Tujuan dari metode ini adalah untuk menyesuaikan nilai instans dengan hasil <instance> <binary operator token> parameter
.
Contoh:
class C1
{
public int Value;
public void operator +=(int x)
{
Value+=x;
}
}
Operator penugasan gabungan dapat mengambil alih operator dengan tanda tangan yang sama yang dideklarasikan dalam kelas dasar, pengubah override
dapat digunakan untuk tujuan ini.
ECMA-335 sudah "dicadangkan" nama khusus berikut untuk operator kenaikan yang ditentukan pengguna: | Nama | Operator | | -----| -------- | |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|
Namun, ini menyatakan bahwa kepatuhan CLS mengharuskan metode operator menjadi metode statis yang tidak batal dengan dua parameter, yaitu cocok dengan operator biner C#. Kita harus mempertimbangkan untuk melonggarkan persyaratan kepatuhan CLS untuk memungkinkan operator membatalkan pengembalian metode instans dengan satu parameter.
Nama berikut harus ditambahkan untuk mendukung versi operator yang diperiksa: | Nama | Operator | | -----| -------- | |op_CheckedAdditionAssignment| diperiksa '+=' | |op_CheckedSubtractionAssignment| diperiksa '-=' | |op_CheckedMultiplicationAssignment| diperiksa '*=' | |op_CheckedDivisionAssignment| diperiksa '/=' |
Operator prefiks kenaikan dan penurunan
Jika x
dalam «op» x
diklasifikasikan sebagai variabel dan versi bahasa baru sedang ditargetkan, maka prioritas diberikan pada operator peningkatan instans sebagai berikut.
Pertama, upaya dilakukan untuk memproses operasi dengan menerapkan resolusi kelebihan beban operator kenaikan instans. Jika proses tidak menghasilkan hasil dan tidak ada kesalahan, maka operasi diproses dengan menerapkan resolusi kelebihan beban operator unary seperti https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#1296-prefix-increment-and-decrement-operators yang saat ini ditentukan.
Jika tidak, operasi «op»x
dievaluasi sebagai berikut.
Jika jenis x
diketahui sebagai jenis referensi, x
dievaluasi untuk mendapatkan instans x₀
, metode operator dipanggil pada instans tersebut, dan x₀
dikembalikan sebagai hasil dari operasi.
Jika x₀
adalah null
, pemanggilan metode operator akan melempar NullReferenceException.
Contohnya:
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 ++() => ...;
}
Jika jenis x
tidak diketahui sebagai jenis referensi:
- Jika hasil kenaikan digunakan,
x
dievaluasi untuk mendapatkan instansx₀
, metode operator dipanggil pada instans tersebut,x₀
ditetapkan kex
danx₀
dikembalikan sebagai hasil dari penugasan gabungan. - Jika tidak, metode operator dipanggil pada
x
.
Perhatikan bahwa efek samping di x
dievaluasi hanya sekali dalam proses.
Contohnya:
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 ++() => ...;
}
Operator kenaikan dan penurunan postfix
Jika hasil operasi digunakan atau x
di x «op»
tidak diklasifikasikan sebagai variabel, atau jika versi bahasa lama yang ditargetkan, operasi diproses dengan menerapkan resolusi kelebihan beban operator unary seperti yang ditentukan saat ini oleh https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#12816-postfix-increment-and-decrement-operators.
Alasan mengapa kita sama sekali tidak mencoba operator kenaikan instans ketika hasil digunakan adalah fakta bahwa jika kita berurusan dengan jenis referensi, tidak mungkin menghasilkan nilai x
sebelum operasi dilakukan jika terjadi mutasi di tempat.
Jika kita berurusan dengan jenis nilai, kita harus membuat salinan pula, dll.
Jika tidak, prioritas diberikan kepada operator peningkatan instans sebagai berikut.
Pertama, upaya dilakukan untuk memproses operasi dengan menerapkan resolusi kelebihan beban operator kenaikan instans. Jika proses tidak menghasilkan hasil dan tidak ada kesalahan, maka operasi diproses dengan menerapkan resolusi kelebihan beban operator unary seperti https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#12816-postfix-increment-and-decrement-operators yang saat ini ditentukan.
Jika tidak, operasi x«op»
dievaluasi sebagai berikut.
Jika jenis x
diketahui sebagai jenis referensi, metode operator dipanggil pada x
.
Jika x
adalah null
, pemanggilan metode operator akan melempar NullReferenceException.
Contohnya:
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 ++() => ...;
}
Jika jenis x
tidak diketahui sebagai jenis referensi, metode operator dipanggil pada x
.
Contohnya:
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 ++() => ...;
}
Resolusi kelebihan beban operator kenaikan instans
Operasi formulir «op» x
atau x «op»
, di mana «op» adalah operator kenaikan instans yang kelebihan beban, dan x
merupakan ekspresi jenis X
, diproses sebagai berikut:
- Set operator yang ditentukan pengguna kandidat yang disediakan oleh
X
untuk operasioperator «op»(x)
ditentukan menggunakan aturan operator kenaikan instans kandidat. - Jika kumpulan operator kandidat yang ditentukan oleh pengguna tidak kosong, maka kumpulan ini menjadi operator kandidat untuk operasi tersebut. Jika tidak, resolusi kelebihan beban tidak menghasilkan hasil.
- Aturan resolusi kelebihan beban diterapkan pada set operator kandidat untuk memilih operator terbaik, dan operator ini menjadi hasil dari proses resolusi kelebihan beban. Jika resolusi kelebihan beban gagal memilih satu operator terbaik, kesalahan waktu pengikatan terjadi.
Operator penambahan instansi kandidat
Mengingat jenis T
dan operasi «op»
, di mana «op»
adalah operator kenaikan instans yang dapat kelebihan beban, set operator yang ditentukan pengguna kandidat yang disediakan ditentukan oleh T
ditentukan sebagai berikut:
- Dalam
unchecked
konteks evaluasi, ini adalah sekelompok operator yang akan diproduksi oleh proses pencarian Anggota ketika hanya operator instansoperator «op»()
yang dianggap cocok dengan namaN
target . - Dalam
checked
konteks evaluasi, ini adalah sekelompok operator yang akan diproduksi oleh proses pencarian Anggota ketika hanya operator instansoperator «op»()
dan instansoperator checked «op»()
yang dianggap cocok dengan namaN
target . Operatoroperator «op»()
yang memiliki deklarasioperator checked «op»()
yang cocok satu sama lain dikecualikan dari grup.
Penugasan gabungan
Paragraf di awal yang menangani dynamic
masih berlaku apa adanya.
Jika tidak, jika x
dalam x «op»= y
diklasifikasikan sebagai variabel dan versi bahasa baru ditargetkan, maka operator penugasan gabungan mendapat prioritas sebagai berikut.
Pertama, upaya dilakukan untuk memproses pengoperasian formulir x «op»= y
dengan menerapkan resolusi kelebihan beban operator penugasan campuran.
Jika proses tidak menghasilkan hasil dan tidak ada kesalahan, maka operasi diproses dengan menerapkan resolusi kelebihan beban operator biner seperti https://github.com/dotnet/csharpstandard/blob/draft-v8/standard/expressions.md#12214-compound-assignment yang saat ini ditentukan.
Jika tidak, operasi akan dievaluasi sebagai berikut.
Jika jenis x
diketahui sebagai jenis referensi, x
dievaluasi untuk mendapatkan instans x₀
, metode operator dipanggil pada instans tersebut dengan y
sebagai argumen, dan x₀
dikembalikan sebagai hasil dari penetapan majemuk.
Jika x₀
adalah null
, pemanggilan metode operator akan melempar NullReferenceException.
Contohnya:
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) => ...;
}
Jika jenis x
tidak diketahui sebagai jenis referensi:
- Jika hasil penugasan gabungan digunakan,
x
dievaluasi untuk mendapatkan sebuah instansx₀
, metode operator dipanggil pada instans tersebut dengany
sebagai argumen,x₀
ditetapkan kex
, danx₀
dikembalikan sebagai hasil dari penugasan gabungan. - Jika tidak, metode operator akan dipanggil pada
x
dengany
sebagai argumen.
Perhatikan bahwa efek samping di x
dievaluasi hanya sekali dalam proses.
Contohnya:
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) => ...;
}
Penyelesaian kelebihan beban operator penugasan gabungan
Operasi formulir x «op»= y
, di mana «op»=
adalah operator penetapan majemuk yang dapat kelebihan beban, x
adalah ekspresi jenis X
diproses sebagai berikut:
- Set operator kandidat yang ditentukan pengguna yang disediakan oleh
X
untuk operasioperator «op»=(y)
ditentukan menggunakan aturan operator penugasan gabungan kandidat. - Jika setidaknya satu operator kandidat yang ditentukan pengguna dalam himpunan berlaku untuk daftar argumen
(y)
, maka ini menjadi himpunan operator kandidat untuk operasi tersebut. Jika tidak, resolusi kelebihan beban tidak menghasilkan hasil. -
Aturan resolusi kelebihan beban diterapkan ke kumpulan operator kandidat untuk memilih operator terbaik sehubungan dengan daftar
(y)
argumen , dan operator ini menjadi hasil dari proses resolusi kelebihan beban. Jika resolusi kelebihan beban gagal memilih satu operator terbaik, kesalahan waktu pengikatan terjadi.
Operator penetapan gabungan kandidat
Mengingat jenis T
dan operasi «op»=
, di mana «op»=
adalah operator penetapan majemuk yang dapat di-overload, kumpulan candidate operator yang didefinisikan pengguna yang disediakan oleh T
ditentukan sebagai berikut:
- Dalam
unchecked
konteks evaluasi, ini adalah sekelompok operator yang akan diproduksi oleh proses pencarian Anggota ketika hanya operator instansoperator «op»=(Y)
yang dianggap cocok dengan namaN
target . - Dalam
checked
konteks evaluasi, ini adalah sekelompok operator yang akan diproduksi oleh proses pencarian Anggota ketika hanya operator instansoperator «op»=(Y)
dan instansoperator checked «op»=(Y)
yang dianggap cocok dengan namaN
target . Operatoroperator «op»=(Y)
yang memiliki deklarasioperator checked «op»=(Y)
yang cocok satu sama lain dikecualikan dari grup.
Buka pertanyaan
[Diselesaikan] Haruskah readonly
pengubah diizinkan dalam struktur?
Rasanya seperti tidak akan ada manfaat dalam memungkinkan untuk menandai metode dengan readonly
ketika seluruh tujuan metode adalah untuk memodifikasi instans.
Kesimpulan: Kami akan mengizinkan readonly
pengubah, tetapi kami tidak akan melonggarkan persyaratan target pada saat ini.
[Diselesaikan] Haruskah bayangan diizinkan?
Jika kelas turunan mendeklarasikan operator 'penugasan gabungan'/'inkrementasi instans' dengan tanda tangan yang sama dengan yang ada di kelas dasar, haruskah kita memerlukan pengubah override
?
Kesimpulan: Bayangan akan diizinkan dengan aturan yang sama dengan metode.
[Diselesaikan] Haruskah kita memiliki penegakan konsistensi antara operator yang dinyatakan dengan +=
dan +
?
Selama LDM-2025-02-12 , kekhawatiran muncul tentang penulis yang secara tidak sengaja mendorong pengguna mereka ke dalam skenario aneh di mana +=
mungkin berfungsi, tetapi +
tidak akan (atau sebaliknya) karena satu formulir menyatakan operator tambahan daripada yang lain.
Kesimpulan: Pemeriksaan tidak akan dilakukan pada konsistensi antara berbagai bentuk operator.
Alternatif
Tetap gunakan metode statis
Kita dapat mempertimbangkan untuk menggunakan metode operator statis di mana instans yang akan dimutasi diteruskan sebagai parameter pertama. Dalam kasus jenis nilai, parameter tersebut harus berupa ref
parameter.
Jika tidak, metode tidak akan dapat melakukan mutasi variabel target. Pada saat yang sama, dalam kasus jenis kelas, parameter tersebut tidak boleh menjadi ref
parameter. Karena dalam kasus kelas, instans yang diteruskan harus diubah, bukan lokasi tempat instans tersebut disimpan. Namun, ketika operator dideklarasikan dalam antarmuka, sering kali tidak diketahui apakah antarmuka hanya akan diimplementasikan oleh kelas, atau hanya oleh struktur. Oleh karena itu, tidak jelas apakah parameter pertama harus menjadi ref
parameter.
Rapat desain
C# feature specifications