Kelebihan muatan sama dengan operator
Sebenarnya ada perbedaan dalam semantik antara dua perbandingan ketika Anda membandingkan null
dengan jenis yang telah membebani ==
operator. foo is null
akan menggunakan perbandingan referensi langsung untuk menentukan hasilnya, sedangkan foo == null
tentu saja akan menjalankan ==
operator yang kelebihan beban jika ada.
Dalam contoh ini saya telah memperkenalkan "bug" pada ==
operator yang kelebihan beban , menyebabkannya selalu mengeluarkan pengecualian jika argumen kedua adalah null
:
void Main()
{
Foo foo = null;
if (foo is null) Console.WriteLine("foo is null"); // This condition is met
if (foo == null) Console.WriteLine("foo == null"); // This will throw an exception
}
public class Foo
{
public static bool operator ==(Foo foo1, Foo foo2)
{
if (object.Equals(foo2, null)) throw new Exception("oops");
return object.Equals(foo1, foo2);
}
// ...
}
Kode IL untuk foo is null
menggunakan ceq
instruksi untuk melakukan perbandingan referensi langsung:
IL_0003: ldloc.0 // foo
IL_0004: ldnull
IL_0005: ceq
Kode IL untuk foo == null
menggunakan panggilan ke operator yang kelebihan beban:
IL_0016: ldloc.0 // foo
IL_0017: ldnull
IL_0018: call UserQuery+Foo.op_Equality
Jadi perbedaannya adalah, bahwa jika Anda menggunakan ==
Anda berisiko menjalankan kode pengguna (yang berpotensi memiliki perilaku yang tidak terduga atau masalah kinerja).
Pembatasan obat generik
Menggunakan is null
konstruk membatasi tipe ke tipe referensi. Kompiler memastikan hal ini, yang berarti Anda tidak dapat menggunakan is null
tipe nilai. Jika Anda memiliki metode generik, Anda tidak akan dapat menggunakan is null
kecuali tipe generik dibatasi menjadi tipe referensi.
bool IsNull<T>(T item) => item is null; // Compile error: CS0403
bool IsNull<T>(T item) => item == null; // Works
bool IsNull<T>(T item) where T : class => item is null; // Works
Terima kasih kepada David Augusto Villa yang telah menunjukkan ini.