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.
Jenis yang ditentukan pengguna dapat membebani operator C# yang telah ditentukan sebelumnya. Artinya, jenis dapat memberikan implementasi kustom operasi jika salah satu atau kedua operan berjenis tersebut. Bagian Operator yang Dapat Kelebihan Beban menunjukkan operator C# mana yang dapat kelebihan beban.
operator
Gunakan kata kunci untuk mendeklarasikan operator. Deklarasi operator harus memenuhi aturan berikut:
- Ini termasuk pengubah
public
. - Operator unary memiliki satu input parameter. Operator biner memiliki dua parameter input. Dalam setiap kasus, setidaknya satu parameter harus memiliki jenis
T
atauT?
di manaT
adalah jenis yang berisi deklarasi operator. - Ini termasuk pengubah
static
, kecuali untuk operator penugasan campuran, seperti+=
. - Operator kenaikan (
++
) dan penurunan (--
) dapat diimplementasikan sebagai metode statis atau instans.
Contoh berikut menentukan struktur yang disederhanakan untuk mewakili angka rasional. Struktur membebani beberapa operator aritmatika:
public struct Fraction
{
private int numerator;
private int denominator;
public Fraction(int numerator, int denominator)
{
if (denominator == 0)
{
throw new ArgumentException("Denominator cannot be zero.", nameof(denominator));
}
this.numerator = numerator;
this.denominator = denominator;
}
public static Fraction operator +(Fraction operand) => operand;
public static Fraction operator -(Fraction operand) => new Fraction(-operand.numerator, operand.denominator);
public static Fraction operator +(Fraction left, Fraction right)
=> new Fraction(left.numerator * right.denominator + right.numerator * left.denominator, left.denominator * right.denominator);
public static Fraction operator -(Fraction left, Fraction right)
=> left + (-right);
public static Fraction operator *(Fraction left, Fraction right)
=> new Fraction(left.numerator * right.numerator, left.denominator * right.denominator);
public static Fraction operator /(Fraction left, Fraction right)
{
if (right.numerator == 0)
{
throw new DivideByZeroException();
}
return new Fraction(left.numerator * right.denominator, left.denominator * right.numerator);
}
// Define increment and decrement to add 1/den, rather than 1/1.
public static Fraction operator ++(Fraction operand)
=> new Fraction(operand.numerator++, operand.denominator);
public static Fraction operator --(Fraction operand) =>
new Fraction(operand.numerator--, operand.denominator);
public override string ToString() => $"{numerator} / {denominator}";
// New operators allowed in C# 14:
public void operator +=(Fraction operand) =>
(numerator, denominator ) =
(
numerator * operand.denominator + operand.numerator * denominator,
denominator * operand.denominator
);
public void operator -=(Fraction operand) =>
(numerator, denominator) =
(
numerator * operand.denominator - operand.numerator * denominator,
denominator * operand.denominator
);
public void operator *=(Fraction operand) =>
(numerator, denominator) =
(
numerator * operand.numerator,
denominator * operand.denominator
);
public void operator /=(Fraction operand)
{
if (operand.numerator == 0)
{
throw new DivideByZeroException();
}
(numerator, denominator) =
(
numerator * operand.denominator,
denominator * operand.numerator
);
}
public void operator ++() => numerator++;
public void operator --() => numerator--;
}
public static class OperatorOverloading
{
public static void Main()
{
var a = new Fraction(5, 4);
var b = new Fraction(1, 2);
Console.WriteLine(-a); // output: -5 / 4
Console.WriteLine(a + b); // output: 14 / 8
Console.WriteLine(a - b); // output: 6 / 8
Console.WriteLine(a * b); // output: 5 / 8
Console.WriteLine(a / b); // output: 10 / 4
}
}
Anda dapat memperluas contoh sebelumnya dengan menentukan konversi implisit dari int
ke Fraction
. Kemudian, operator yang kelebihan beban akan mendukung argumen dari dua jenis tersebut. Artinya, akan menjadi mungkin untuk menambahkan bilangan bulat ke pecahan dan mendapatkan pecahan sebagai hasilnya.
Anda juga menggunakan operator
kata kunci untuk menentukan konversi jenis kustom. Untuk informasi selengkapnya, lihat Operator konversi yang ditentukan pengguna.
Operator yang dapat di-overload
Tabel berikut ini memperlihatkan operator yang bisa kelebihan beban:
Para Operator | Catatan |
---|---|
+x , , -x !x , ~x , ++ , -- , , true ,false |
Operator true dan false harus kelebihan beban bersama-sama. |
x + y , , x - y x * y , x / y , , x % y ,x & y , x | y , x ^ y ,x << y , , x >> y x >>> y |
|
x == y , , x != y x < y , x > y , , x <= y ,x >= y |
Harus kelebihan beban berpasangan sebagai berikut: == dan != , < dan > , <= dan >= . |
+= , , -= *= , /= , %= , &= , \|= , ^= , <<= , , , >>= >>>= |
Operator penugasan gabungan dapat kelebihan beban di C# 14 dan yang lebih baru. |
Operator yang kelebihan beban penugasan gabungan harus mengikuti aturan berikut:
- Ini harus mencakup pengubah
public
. - Ini tidak dapat menyertakan pengubah
static
. - Tipe pengembalian harus
void
. - Deklarasi harus mencakup satu parameter, yang mewakili sisi kanan pengalokasian gabungan.
Dimulai dengan C# 14, operator kenaikan (++
) dan penurunan (--
) dapat kelebihan beban sebagai anggota instans. Operator instans dapat meningkatkan performa dengan menghindari pembuatan instans baru. Operator instans harus mengikuti aturan ini:
- Ini harus mencakup pengubah
public
. - Ini tidak dapat menyertakan pengubah
static
. - Tipe pengembalian harus
void
. - Ini tidak dapat mendeklarasikan parameter apa pun, bahkan jika parameter tersebut memiliki nilai default.
Operator yang tidak dapat di-overload
Tabel berikut ini memperlihatkan operator yang tidak dapat kelebihan beban:
Para Operator | Alternatif |
---|---|
x && y , x || y |
Overload kedua operator true dan false , serta operator & atau | . Untuk informasi selengkapnya, lihat Operator logis kondisional yang ditentukan pengguna. |
a[i] , a?[i] |
Tentukan pengindeks. |
(T)x |
Definisikan konversi tipe kustom yang dilakukan oleh ekspresi cast. Untuk informasi selengkapnya, lihat Operator konversi yang ditentukan pengguna. |
^x , x = y , x.y , x?.y , c ? t : f , x ?? y , ??= y x..y , x->y , => , f(x) , as , await , checked , unchecked , default , delegate , is , nameof , new sizeof , , stackalloc switch , , typeof ,with |
Tidak ada. |
Sebelum C# 14, operator senyawa tidak dapat kelebihan beban. Kelebihan beban operator biner yang sesuai secara implisit membebani operator penetapan majemuk yang sesuai.
Resolusi kelebihan beban operator
Penting
Bagian ini berlaku untuk C# 14 dan yang lebih baru. Sebelum C# 14, operator penugasan gabungan yang ditentukan pengguna, serta operator peningkatan dan penurunan instans, tidak diizinkan.
Jika x
diklasifikasikan sebagai variabel dalam ekspresi penetapan gabungan seperti x «op»= y
, operator instans lebih disukai daripada operator statis apa pun untuk «op»
. Jika operator «op»=
yang di-overload tidak dinyatakan untuk tipe x
atau x
tidak diklasifikasikan sebagai variabel, operator statis akan digunakan.
Untuk operator ++
postfix , jika x
tidak diklasifikasikan sebagai variabel atau ekspresi x++
digunakan, instans operator++
diabaikan. Jika sebaliknya, preferensi diberikan kepada instans operator ++
. Contohnya,
x++; // Instance operator++ preferred.
y = x++; // instance operator++ isn't considered.
Alasan untuk aturan ini adalah bahwa y
harus ditetapkan ke nilai x
sebelum dinaikkan. Pengkompilasi tidak dapat menentukan implementasi yang ditentukan pengguna dalam tipe referensi.
Untuk operator awalan ++
, jika x
diklasifikasikan sebagai variabel dalam ++x
, operator instans lebih disukai daripada operator unary statis.
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat bagian berikut dari spesifikasi bahasa C#: