Berikut ini akan menyebabkan rekursi tak terbatas pada == metode kelebihan beban operator
Foo foo1 = null;
Foo foo2 = new Foo();
Assert.IsFalse(foo1 == foo2);
public static bool operator ==(Foo foo1, Foo foo2) {
if (foo1 == null) return foo2 == null;
return foo1.Equals(foo2);
}
Bagaimana cara memeriksa nulls?
c#
.net
operator-overloading
Andrew Jones
sumber
sumber
Assert.IsFalse(foo2 == foo1);
foo1.Equals(foo2)
artinya jika, misalnya, saya inginfoo1 == foo2
hanya jikafoo1.x == foo2.x && foo1.y == foo2.y
? Bukankah ini menjawab mengabaikan kasus dimanafoo1 != null
tapifoo2 == null
?if (foo1 is null) return foo2 is null;
Transmisikan ke objek dalam metode kelebihan beban:
sumber
(object)foo1 == null
ataufoo1 == (object)null
akan pergi ke kelebihan beban bawaan==(object, object)
dan bukan ke beban berlebih yang ditentukan pengguna==(Foo, Foo)
. Ini seperti resolusi yang berlebihan pada metode.Gunakan
ReferenceEquals
. Dari forum MSDN :sumber
Mencoba
Object.ReferenceEquals(foo1, null)
Bagaimanapun, saya tidak akan merekomendasikan membebani
==
operator secara berlebihan ; itu harus digunakan untuk membandingkan referensi, dan digunakanEquals
untuk perbandingan "semantik".sumber
Jika saya telah mengganti
bool Equals(object obj)
dan saya ingin operator==
danFoo.Equals(object obj)
mengembalikan nilai yang sama, saya biasanya menerapkan!=
operator seperti ini:Operator
==
kemudian akan setelah melakukan semua pemeriksaan nol untuk saya akhirnya memanggilfoo1.Equals(foo2)
bahwa saya telah diganti untuk melakukan pemeriksaan sebenarnya jika keduanya sama.sumber
Object.Equals(Object, Object)
berdampinganObject.ReferenceEquals(Object, Object)
, cukup jelas bahwaObject.Equals(Object, Object)
melakukan semua seperti yang disarankan dalam jawaban lain di luar kotak. Mengapa tidak menggunakannya?==
operator jika yang Anda inginkan hanyalah perilaku default. Anda sebaiknya hanya membebani saat Anda perlu menerapkan logika perbandingan khusus, misalnya, sesuatu yang lebih dari sekadar pemeriksaan persamaan referensi.==
diinginkan (pertanyaan menyiratkannya) Saya hanya mendukung jawaban ini dengan menyarankan bahwaObject.Equals(Object, Object)
membuat trik lain seperti menggunakanReferenceEquals
atau gips eksplisit tidak diperlukan (jadi "mengapa tidak menggunakannya?", "itu" menjadiEquals(Object, Object)
). Bahkan jika tidak terkait poin Anda juga benar, dan saya akan melangkah lebih jauh: hanya membebani==
objek yang dapat kita klasifikasikan sebagai "objek nilai".Object.Equals(Object, Object)
pada gilirannya memanggil Object.Equals (Object) yang merupakan metode virtual yang mungkin ditimpa oleh Foo. Fakta bahwa Anda telah memasukkan panggilan virtual ke dalam pemeriksaan kesetaraan mungkin memengaruhi kemampuan penyusun untuk mengoptimalkan (misalnya sebaris) panggilan ini. Ini mungkin dapat diabaikan untuk sebagian besar tujuan, tetapi dalam kasus tertentu, biaya kecil dalam operator kesetaraan dapat berarti biaya yang sangat besar untuk loop atau struktur data yang diurutkan.Jika Anda menggunakan C # 7 atau yang lebih baru, Anda dapat menggunakan pencocokan pola konstan nol:
Ini memberi Anda kode yang sedikit lebih rapi daripada yang memanggil objek .ReferenceEquals (foo1, null)
sumber
public static bool operator==( Foo foo1, Foo foo2 ) => foo1?.Equals( foo2 ) ?? foo2 is null;
Sebenarnya ada cara yang lebih sederhana untuk memeriksa
null
dalam kasus ini:Itu dia!
Fitur ini diperkenalkan di C # 7
sumber
Pendekatan saya adalah melakukan
di mana saya mengandalkan
object
operator kesetaraan sendiri yang tidak bisa salah. Atau metode ekstensi khusus (dan kelebihan beban):atau untuk menangani lebih banyak kasus, mungkin:
Batasan mencegah
IsNull
jenis nilai. Sekarang semanis meneleponyang berarti saya memiliki satu gaya konsisten / tidak-rawan kesalahan dalam memeriksa nulls di seluruh. Saya juga telah menemukan
(object)item == null
sangat sangat sangat sedikit lebih cepat daripadaObject.ReferenceEquals(item, null)
, tetapi hanya jika itu penting (saya saat ini sedang mengerjakan sesuatu di mana saya telah mengoptimalkan mikro semuanya!).Untuk melihat panduan lengkap tentang penerapan pemeriksaan kesetaraan, lihat Apa itu "Praktik Terbaik" Untuk Membandingkan Dua Contoh dari Jenis Referensi?
sumber
DbNull
, IMO kasus di mana ini tidak akan menghasilkan masalah yang terkait dengan SRP cukup jarang. Hanya menunjukkan bau kode, itu bisa sangat tepat.Equals(Object, Object)
Metode statis menunjukkan apakah dua objek,objA
danobjB
, sama. Ini juga memungkinkan Anda untuk menguji objek yang nilainyanull
untuk persamaan. Ini membandingkanobjA
danobjB
untuk kesetaraan sebagai berikut:true
. Tes ini setara dengan memanggilReferenceEquals
metode. Selain itu, jika keduanyaobjA
danobjB
adalahnull
, metode akan kembalitrue
.objA
atauobjB
itunull
. Jika demikian, itu kembalifalse
. Jika dua objek tidak mewakili referensi objek yang sama dan tidak juganull
, itu akan memanggilobjA.Equals(objB)
dan mengembalikan hasilnya. Artinya jikaobjA
menimpaObject.Equals(Object)
metode, penggantian ini dipanggil..
sumber
membalas lebih ke operator utama bagaimana membandingkan dengan null yang mengalihkan ke sini sebagai duplikat.
Dalam kasus di mana ini dilakukan untuk mendukung Objek Nilai, saya menemukan notasi baru berguna, dan ingin memastikan hanya ada satu tempat di mana perbandingan dibuat. Juga memanfaatkan Object.Equals (A, B) menyederhanakan pemeriksaan null.
Ini akan membebani ==,! =, Equals, dan GetHashCode
Untuk objek yang lebih rumit, tambahkan perbandingan tambahan di Equals dan GetHashCode yang lebih kaya.
sumber
Untuk sintaksis modern dan ringkas:
sumber
Lihat ini
referensi Panduan untuk Overloading Sama () dan Operator ==
sumber
Anda dapat mencoba menggunakan properti objek dan menangkap NullReferenceException yang dihasilkan. Jika properti yang Anda coba diwarisi atau diganti dari Object, maka ini berfungsi untuk semua kelas.
sumber