C # perbedaan antara == dan Equals ()

548

Saya memiliki kondisi dalam aplikasi silverlight yang membandingkan 2 string, untuk beberapa alasan ketika saya menggunakannya ==mengembalikan false sementara .Equals()mengembalikan true .

Ini kodenya:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack"))
{
    // Execute code
}

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack")
{
    // Execute code
}

Ada alasan mengapa ini terjadi?

Drahcir
sumber
8
String override ==, tetapi operator tidak polimorfik. Dalam kode ini, ==operator dipanggil pada tipe object, yang melakukan perbandingan identitas daripada nilai satu.
Drew Noakes
12
Untuk memperluas komentar @DrewNoakes ': Kompiler memilih ==kelebihan berdasarkan pada jenis waktu kompilasi operan. The Contentproperti object. Operator tidak virtual, sehingga implementasi standar ==disebut, memberikan referensi kesetaraan referensi. Dengan Equals, panggilan masuk ke metode virtual object.Equals(object); stringmengganti metode ini dan melakukan perbandingan ordinal pada konten string. Lihat msdn.microsoft.com/en-us/library/fkfd9eh8(v=vs.110).aspx dan referenceource.microsoft.com/#mscorlib/system/string.cs,507 .
phoog
6
Penjelasan @ phoog tepat. Perlu dicatat bahwa ketika sisi kiri ==memiliki tipe waktu kompilasi objectdan sisi kanan memiliki tipe waktu kompilasi string, maka kompiler C # harus memilih (bermasalah, dalam hal ini) kelebihan beban operator ==(object, object); tetapi itu akan mengeluarkan peringatan waktu kompilasi bahwa itu mungkin tidak disengaja. Jadi baca peringatan waktu kompilasi! Untuk memperbaiki masalah ini dan masih menggunakan ==, masukkan sisi kiri ke string. Jika saya ingat dengan benar, teks peringatan menyarankan hal itu.
Jeppe Stig Nielsen
1
@JeppeStigNielsen +1 untuk saran membaca peringatan kompiler. Bahkan lebih baik: aktifkan opsi peringatan sebagai kesalahan untuk memaksa semua orang memperhatikannya.
phoog

Jawaban:

429

Ketika ==digunakan pada ekspresi tipe object, itu akan berubah menjadi System.Object.ReferenceEquals.

Equalshanyalah sebuah virtualmetode dan berperilaku seperti itu, sehingga versi yang diganti akan digunakan (yang, untuk stringtipe membandingkan konten).

Mehrdad Afshari
sumber
57
Kecuali jika operator secara khusus diimplementasikan di kelas
Dominic Cronin
23
@ DominicCronin Ini tidak benar. Bahkan jika == diimplementasikan di kelas itu akan diabaikan karena tipe di sebelah kiri perbandingan adalah objek. Sepertinya kelebihan operator ditentukan pada waktu kompilasi dan pada waktu kompilasi yang ia ketahui adalah sisi kiri adalah objek.
MikeKulls
4
@DominicCronin Saya percaya pernyataan pertama Anda benar bahwa == akan memutuskan untuk keberatan, tetapi pernyataan kedua Anda bahwa operator overload menyelesaikan dengan cara yang sama tidak. Mereka sangat berbeda itulah sebabnya. Equals akan menyelesaikan ke string sementara == akan memutuskan untuk objek.
MikeKulls
8
Agar jelas, objectketik (perhatikan font monospace) secara teknis dimaksudkan sebagai "ekspresi tipe System.Object". Itu tidak ada hubungannya dengan jenis runtime dari instance yang disebut oleh ekspresi. Saya pikir pernyataan "operator yang ditetapkan pengguna diperlakukan seperti virtualmetode" sangat menyesatkan. Mereka diperlakukan seperti metode kelebihan beban dan hanya bergantung pada jenis waktu kompilasi operan. Bahkan, setelah himpunan operator yang ditentukan pengguna dihitung, sisa prosedur penjilidan akan menjadi persis metode algoritma resolusi berlebih
Mehrdad Afshari
4
@DominicCronin Bagian yang menyesatkan adalah bahwa virtualresolusi metode tergantung pada jenis runtime yang sebenarnya dari sebuah instance, sedangkan yang benar - benar diabaikan dalam resolusi kelebihan operator, dan memang itulah inti dari jawaban saya.
Mehrdad Afshari
314

Ketika membandingkan referensi objek ke string (bahkan jika referensi objek mengacu pada string), perilaku khusus ==operator khusus untuk kelas string diabaikan.

Biasanya (ketika tidak berurusan dengan string, yaitu), Equalsmembandingkan nilai , sambil ==membandingkan referensi objek . Jika dua objek yang Anda bandingkan merujuk ke instance yang persis sama dari suatu objek, maka keduanya akan mengembalikan true, tetapi jika seseorang memiliki konten yang sama dan berasal dari sumber yang berbeda (adalah instance terpisah dengan data yang sama), hanya Equals yang akan kembali benar. Namun, seperti yang disebutkan dalam komentar, string adalah kasus khusus karena menimpa ==operator sehingga ketika berurusan murni dengan referensi string (dan bukan referensi objek), hanya nilai yang dibandingkan bahkan jika mereka adalah contoh yang terpisah. Kode berikut menggambarkan perbedaan perilaku yang halus:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Outputnya adalah:

True True True
False True True
False False True
BlueMonkMN
sumber
8
Spot on. Operator '==' membandingkan referensi objek (perbandingan dangkal) sedangkan .Equals () membandingkan konten objek (perbandingan mendalam). Seperti yang dikatakan @mehrdad, .Equals () diganti untuk memberikan perbandingan konten yang mendalam.
Andrew
1
Saya akan meninggalkan pos di sini karena saya pikir sangat berharga untuk menekankan apa yang tidak terjadi karena Anda harus memperhatikannya dengan saksama. (Dan saya pikir kode untuk menunjukkan pemahaman yang benar dan yang salah juga bermanfaat.) Saya harap peringkatnya tidak akan di bawah 0.
BlueMonkMN
5
Tentunya String mengimplementasikan operator == kustom. Jika tidak maka menggunakan == tidak akan membandingkan konten. Jadi String adalah contoh yang buruk untuk digunakan di sini, karena tidak membantu kita memahami kasus umum di mana tidak ada operator kustom yang didefinisikan.
Dominic Cronin
6
+1 untuk contoh kode epik, yang membuat saya memahami ini. Memperlihatkan case umum dari tipe statis (tipe Left Hand Side) menjadi objek dan case spesifik dari tipe statis (/ tipe RHS) menjadi string. Dan menyentuh dengan baik pada string magang.
barlop
2
@badsamaritan Karena interning string
Alexander Derck
46

==dan .Equalskeduanya tergantung pada perilaku yang ditentukan dalam tipe aktual dan tipe aktual di situs panggilan. Keduanya hanya metode / operator yang dapat ditimpa pada jenis apa pun dan diberi perilaku yang diinginkan penulis. Dalam pengalaman saya, saya menemukan itu biasa bagi orang untuk mengimplementasikan .Equalspada suatu objek tetapi mengabaikan untuk mengimplementasikan operator ==. Ini berarti bahwa .Equalssebenarnya akan mengukur kesetaraan nilai sementara ==akan mengukur apakah mereka adalah referensi yang sama atau tidak.

Ketika saya bekerja dengan tipe baru yang definisinya dalam fluks atau menulis algoritma generik, saya menemukan praktik terbaik adalah sebagai berikut

  • Jika saya ingin membandingkan referensi dalam C #, saya menggunakan Object.ReferenceEqualslangsung (tidak diperlukan dalam kasus umum)
  • Jika saya ingin membandingkan nilai yang saya gunakan EqualityComparer<T>.Default

Dalam beberapa kasus ketika saya merasa penggunaan ==ambigu saya secara eksplisit akan menggunakan Object.Referenceequals dalam kode untuk menghapus ambiguitas.

Eric Lippert baru-baru ini membuat posting blog tentang masalah mengapa ada 2 metode kesetaraan di CLR. Ini layak dibaca

JaredPar
sumber
Nah Jared, Anda langsung melanggar terkenal Jeff "Kode terbaik adalah tidak ada kode sama sekali di sini." Apakah ini benar? Di sisi lain, saya bisa melihat di mana ini berasal dan mengapa mungkin diinginkan untuk membuat semantik eksplisit. Untuk kasus ini, saya sangat suka cara VB berurusan dengan kesetaraan objek. Ini pendek dan tidak ambigu.
Konrad Rudolph
@ Konrad, saya benar-benar seharusnya mengatakan "ketika saya tidak terbiasa dengan tipe, saya menemukan praktik terbaik adalah sebagai berikut" Ya VB memiliki semantik yang jauh lebih baik di sini karena benar-benar memisahkan nilai dan persamaan referensi. C # mencampur keduanya bersama-sama dan kadang-kadang menyebabkan kesalahan ambiguitas.
JaredPar
10
Ini tidak sepenuhnya benar. == tidak dapat diganti, ini adalah metode statis. Itu hanya bisa kelebihan beban, yang merupakan perbedaan penting. Jadi kode yang dieksekusi untuk operator == ditautkan pada waktu kompilasi, sedangkan Equals adalah virtual dan ditemukan pada waktu eksekusi.
Stefan Steinegger
20

== Operator

  1. Jika operan adalah Tipe Nilai dan nilainya sama, ia mengembalikan true else false.
  2. Jika operan adalah Tipe Referensi dengan pengecualian string dan keduanya merujuk ke instance yang sama (objek yang sama), itu mengembalikan true else false.
  3. Jika operan adalah tipe string dan nilainya sama, ia mengembalikan true else false.

. Sama dengan

  1. Jika operan adalah Jenis Referensi , ia melakukan Referensi Kesetaraan yaitu jika keduanya merujuk ke instance yang sama (objek yang sama), ia mengembalikan true else false.
  2. Jika Operand adalah Jenis Nilai maka tidak seperti operator == ia memeriksa jenisnya terlebih dahulu dan jika jenisnya sama, ia melakukan == operator lain jika ia mengembalikan false.
Kashif
sumber
2
Ini tidak benar. The ==operator dapat kelebihan beban untuk semua jenis, bukan hanya tali. Menjelaskan pengecualian kasus khusus hanya untuk string yang merepresentasikan semantik operator. Akan lebih akurat, walaupun mungkin tidak terlalu berguna, untuk mengatakan "jika operan adalah tipe referensi, ia mengembalikan true jika operan merujuk ke objek yang sama, kecuali ada kelebihan beban yang berlaku, dalam hal implementasi dari kelebihan itu menentukan hasilnya ". Hal yang sama berlaku untuk Equalsdengan komplikasi tambahan bahwa itu adalah metode virtual, sehingga perilakunya dapat diganti serta kelebihan beban.
phoog
19

Pertama, ada adalah perbedaan. Untuk angka

> 2 == 2.0
True

> 2.Equals(2.0)
False

Dan untuk string

> string x = null;
> x == null
True

> x.Equals(null)
NullReferenceException

Dalam kedua kasus, ==berperilaku lebih bermanfaat daripada.Equals

Kolonel Panic
sumber
2
Saya tidak yakin saya akan menganggap pemaksaan tipe integral untuk tipe floating-point dengan ==operator sebagai hal yang baik. Sebagai contoh, haruskah 16777216.0f sama dengan (int) 16777217, (ganda) 16777217.0, keduanya, atau tidak? Perbandingan antara tipe integral baik-baik saja, tetapi perbandingan floating-point hanya boleh dilakukan IMHO dengan nilai-nilai yang secara eksplisit dilemparkan ke jenis yang cocok. Perbandingan a floatdengan sesuatu selain dari float, atau doubledengan sesuatu selain dari double, menurut saya sebagai bau kode utama yang tidak boleh dikompilasi tanpa diagnostik.
supercat
1
@supercat saya setuju - itu menyedihkan yang x == ytidak menyiratkan x/3 == y/3(coba x = 5dan y = 5.0).
Kolonel Panic
Saya menganggap penggunaan /untuk divisi integer menjadi cacat dalam desain C # dan Java. Pascal divdan bahkan VB.NET's ` are much better. The problems with == `lebih buruk, meskipun: x==ydan y==ztidak menyiratkan itu x==z(pertimbangkan tiga angka dalam komentar saya sebelumnya). Adapun hubungan yang Anda sarankan, bahkan jika xdan ykeduanya floatatau keduanya double, x.equals((Object)y)tidak menyiratkan bahwa 1.0f/x == 1.0f / y` (jika saya memiliki druthers saya, itu akan menjamin bahwa; bahkan jika ==tidak membedakan positif dan nol, Equalsseharusnya).
supercat
Itu normal, karena parameter pertama Equals () adalah string!
Whiplash
17

Sejauh yang saya mengerti jawabannya sederhana:

  1. == membandingkan referensi objek.
  2. .Equals membandingkan konten objek.
  3. String tipe data selalu bertindak seperti perbandingan konten.

Saya harap saya benar dan itu menjawab pertanyaan Anda.

Liraz Shaka Amir
sumber
15

Saya akan menambahkan bahwa jika Anda melemparkan objek Anda ke string maka itu akan berfungsi dengan benar. Inilah sebabnya mengapa kompiler akan memberi Anda peringatan yang mengatakan:

Kemungkinan perbandingan referensi yang tidak diinginkan; untuk mendapatkan perbandingan nilai, masukkan sisi kiri untuk mengetik 'string'

MikeKulls
sumber
1
Persis. @DominicCronin: Selalu perhatikan peringatan waktu kompilasi. Jika sudah object expr = XXX; if (expr == "Energy") { ... }, maka karena sisi kiri adalah tipe waktu kompilasi object, kompiler harus menggunakan kelebihan beban operator ==(object, object). Ini memeriksa kesetaraan referensi. Apakah itu akan memberi trueatau falsesulit diprediksi karena string magang . Jika Anda tahu sisi kiri nulljenis atau tipenya string, lemparkan ke sisi kiri stringsebelum digunakan ==.
Jeppe Stig Nielsen
untuk menempatkan bagian dari cara lain itu. == (dalam menentukan apakah ia menggunakan referensi kesetaraan atau kesetaraan nilai) tergantung pada jenis waktu kompilasi / tipe statis / tipe sisi kiri. (itulah tipe yang diselesaikan dalam analisis waktu kompilasi). Daripada tipe runtime / tipe dinamis / tipe RHS. Kode BlueMonkMN menunjukkan itu, meskipun tidak dengan casting.
barlop
5

Karena versi statis dari .Equalmetode ini tidak disebutkan sejauh ini, saya ingin menambahkan ini di sini untuk meringkas dan membandingkan 3 variasi.

MyString.Equals("Somestring"))          //Method 1
MyString == "Somestring"                //Method 2
String.Equals("Somestring", MyString);  //Method 3 (static String.Equals method) - better

di mana MyStringvariabel yang berasal dari tempat lain dalam kode.

Info latar belakang dan musim panas:

Di Jawa menggunakan ==untuk membandingkan string tidak boleh digunakan. Saya menyebutkan ini jika Anda perlu menggunakan kedua bahasa dan juga untuk memberi tahu Anda bahwa penggunaan ==juga dapat diganti dengan sesuatu yang lebih baik di C #.

Dalam C # tidak ada perbedaan praktis untuk membandingkan string menggunakan Metode 1 atau Metode 2 selama keduanya adalah tipe string. Namun, jika satu adalah nol, satu dari jenis lain (seperti bilangan bulat), atau satu mewakili objek yang memiliki referensi berbeda, maka, seperti yang ditunjukkan pertanyaan awal, Anda mungkin mengalami bahwa membandingkan konten untuk kesetaraan mungkin tidak menghasilkan apa kamu mengharapkan.

Solusi yang disarankan:

Karena menggunakan ==tidak persis sama dengan menggunakan .Equalssaat membandingkan sesuatu, Anda dapat menggunakan metode String.Equals statis sebagai gantinya. Dengan cara ini, jika kedua belah pihak bukan tipe yang sama Anda masih akan membandingkan konten dan jika salah satu adalah nol, Anda akan menghindari pengecualian.

   bool areEqual = String.Equals("Somestring", MyString);  

Memang sedikit lebih untuk menulis, tetapi menurut saya, lebih aman digunakan.

Berikut ini beberapa info yang disalin dari Microsoft:

public static bool Equals (string a, string b);

Parameter

a Tali

String pertama yang dibandingkan, atau null.

b Tali

String kedua untuk membandingkan, atau null.

Kembali Boolean

truejika nilai asama dengan nilai b; jika tidak false,. Jika keduanya adan bini null, metode kembali true.

Mario Levesque
sumber
5

Sama seperti tambahan untuk jawaban yang sudah baik: Perilaku ini TIDAK terbatas pada String atau membandingkan berbagai tipe angka. Bahkan jika kedua elemen tersebut bertipe objek dengan tipe dasar yang sama. "==" tidak akan berfungsi.

Tangkapan layar berikut menunjukkan hasil membandingkan dua objek {int} - nilai

Contoh Dari VS2017

Ole Albers
sumber
2

Saya agak bingung di sini. Jika tipe runtime dari Konten adalah tipe string, maka == dan Persamaan harus mengembalikan true. Namun, karena hal ini tampaknya tidak terjadi, maka jenis runtime dari Konten bukan string dan memanggil Persamaan di atasnya sedang melakukan kesetaraan referensial dan ini menjelaskan mengapa Persamaan ("Serangan Energi") gagal. Namun, dalam kasus kedua, keputusan tentang overloaded == operator statis harus dipanggil dibuat pada waktu kompilasi dan keputusan ini tampaknya == (string, string). ini menunjukkan kepada saya bahwa Konten menyediakan konversi tersirat ke string.

Mehmet Aras
sumber
2
Anda memilikinya kembali ke depan. Untuk memulai, Persamaan ("Serangan Energi") tidak gagal, == adalah yang mengembalikan false. == gagal karena menggunakan == dari objek, bukan string.
MikeKulls
Secara default, operator == menguji kesetaraan referensi dengan menentukan apakah dua referensi mengindikasikan objek yang sama. Oleh karena itu, tipe referensi tidak harus mengimplementasikan operator == untuk mendapatkan fungsionalitas ini. Ketika suatu tipe tidak dapat diubah, yaitu, data yang terkandung dalam instance tidak dapat diubah, operator overloading == untuk membandingkan kesetaraan nilai dan bukannya kesetaraan referensi dapat berguna karena, sebagai objek yang tidak dapat diubah, mereka dapat dianggap sama selama karena mereka memiliki nilai yang sama. Ini bukan ide yang baik untuk menimpa operator == dalam tipe yang tidak dapat diubah.
Wajeed-MSFT
2

Ada dimensi lain dari jawaban sebelumnya oleh @BlueMonkMN. Dimensi tambahan adalah bahwa jawaban untuk pertanyaan judul @ Drahcir seperti yang dinyatakan juga tergantung pada bagaimana kita sampai pada stringnilainya. Menggambarkan:

string s1 = "test";
string s2 = "test";
string s3 = "test1".Substring(0, 4);
object s4 = s3;
string s5 = "te" + "st";
object s6 = s5;
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2));

Console.WriteLine("\n  Case1 - A method changes the value:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

Console.WriteLine("\n  Case2 - Having only literals allows to arrive at a literal:");
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5));
Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));

Outputnya adalah:

True True True

  Case1 - A method changes the value:
False True True
False False True

  Case2 - Having only literals allows to arrive at a literal:
True True True
True True True
Novichok
sumber
2

Menambahkan satu poin lagi ke jawabannya.

.EqualsTo() Metode memberi Anda ketentuan untuk membandingkan dengan budaya dan case sensitif.

Bala
sumber
0

The ==token C # digunakan untuk dua operator kesetaraan-cek yang berbeda. Ketika kompiler menemukan token itu, itu akan memeriksa apakah salah satu jenis yang dibandingkan telah menerapkan kelebihan operator-kesetaraan untuk salah satu jenis kombinasi spesifik yang sedang dibandingkan (*), atau untuk kombinasi jenis yang kedua jenis dapat dikonversi. Jika kompiler menemukan kelebihan seperti itu, ia akan menggunakannya. Jika tidak, jika kedua tipe tersebut adalah tipe referensi dan mereka bukan kelas yang tidak terkait (bisa berupa antarmuka, atau mungkin kelas terkait), kompiler akan dianggap ==sebagai operator perbandingan-referensi. Jika tidak ada ketentuan yang berlaku, kompilasi akan gagal.

Perhatikan bahwa beberapa bahasa lain menggunakan token terpisah untuk dua operator pemeriksa kesetaraan. Di VB.NET, misalnya, =token digunakan dalam ekspresi semata-mata untuk operator pemeriksa kesetaraan yang kelebihan beban, dan Isdigunakan sebagai operator uji-referensi atau null-test. Suatu untuk digunakan =pada suatu tipe yang tidak mengesampingkan operator pemeriksa kesetaraan akan gagal, sebagaimana akan berusaha digunakan Isuntuk tujuan apa pun selain menguji kesetaraan referensi atau nolitas.

(*) Jenis umumnya hanya kelebihan beban kesetaraan untuk dibandingkan dengan mereka sendiri, tetapi mungkin berguna untuk jenis kelebihan beban operator kesetaraan untuk perbandingan dengan jenis tertentu lainnya; misalnya, intdapat memiliki (dan IMHO seharusnya tetapi tidak) mendefinisikan operator kesetaraan untuk perbandingan float, sehingga 16777217 tidak akan melaporkan dirinya sama dengan 16777216f. Karena, karena tidak ada operator yang didefinisikan, C # akan mempromosikan intke float, membulatkannya ke 16777216f sebelum operator pemeriksa kesetaraan melihatnya; operator itu kemudian melihat dua angka floating-point yang sama dan melaporkannya sebagai sama, tidak mengetahui pembulatan yang terjadi.

supercat
sumber
Daripada memiliki perbandingan int-to-float mengembalikan false, saya lebih suka pendekatan yang menggunakan F #, yang melarang perbandingan semacam itu sama sekali. Kemudian programmer dapat memutuskan apakah dan bagaimana menangani fakta bahwa nilai-nilai memiliki tipe yang berbeda. Karena kadang-kadang, setelah semua, kita lakukan ingin memperlakukan 3sebagai sama dengan 3.0f. Jika kami mengharuskan programmer untuk mengatakan apa yang dimaksudkan dalam setiap kasus, maka tidak ada bahaya perilaku default yang mengarah ke hasil yang tidak diinginkan, karena tidak ada perilaku default.
phoog
@ phoog: Perasaan pribadi saya adalah bahwa bahasa harus memiliki alat uji kesetaraan "normal" yang menerapkan hubungan ekivalensi, dan melarang semua kombinasi operan yang tidak diinginkan. Saya tidak melihat keuntungan besar memiliki pemerataan pemeriksaan bahasa antara bilangan bulat dan float dengan mengonfirmasi bahwa float tepat mewakili seluruh angka yang cocok dengan int, dibandingkan hanya melarang perbandingan seperti itu, tetapi akan mempertimbangkan pendekatan mana yang lebih baik daripada memiliki bahasa yang berkinerja konversi lossy sebelum perbandingan.
supercat
0

Jawaban dan contoh yang sangat bagus!

Saya hanya ingin menambahkan perbedaan mendasar antara keduanya,

Operator seperti ==tidak polimorfik, sementara Equalsitu

Dengan konsep itu dalam pikiran, jika Anda menemukan contoh apa pun (dengan melihat jenis referensi tangan kiri dan kanan, dan memeriksa / mengetahui apakah jenisnya benar-benar memiliki == operator kelebihan beban dan Persamaan ditimpa) Anda yakin untuk mendapatkan jawaban yang benar .

Manish Basantani
sumber
-2

==

Operator == dapat digunakan untuk membandingkan dua variabel apa pun, dan itu hanya membandingkan bit .

int a = 3;
byte b = 3;
if (a == b) { // true }

Catatan: ada lebih banyak nol di sisi kiri int tetapi kami tidak peduli tentang itu di sini.

int a (00000011) == byte b (00000011)

Ingat operator == hanya peduli tentang pola bit dalam variabel.

Gunakan == Jika dua referensi (primitif) merujuk ke objek yang sama di heap.

Aturannya sama apakah variabelnya adalah referensi atau primitif.

Foo a = new Foo();
Foo b = new Foo();
Foo c = a;

if (a == b) { // false }
if (a == c) { // true }
if (b == c) { // false }

a == c benar a == b salah

pola bit sama untuk a dan c, sehingga keduanya sama dengan menggunakan ==.

Sama():

Gunakan metode equals () untuk melihat apakah dua objek berbeda sama .

Seperti dua objek String yang berbeda yang keduanya mewakili karakter dalam "Jane"

Sanchit
sumber
2
Ini salah. Pertimbangkan berikut: object a = 3; object b = 3; Console.WriteLine(a == b);. Outputnya salah, meskipun pola bit dari nilai-nilai itu sama. Jenis-jenis operan juga penting. Alasan kami "tidak peduli" tentang jumlah nol yang berbeda dalam contoh Anda adalah bahwa pada saat kami memanggil operator yang sama, jumlah nol sebenarnya sama , karena konversi implisit.
phoog
-2

Satu-satunya perbedaan antara Equal dan == adalah pada perbandingan jenis objek. dalam kasus lain, seperti jenis referensi dan jenis nilai, mereka hampir sama (baik keduanya adalah kesetaraan bit-bijaksana atau keduanya adalah persamaan referensi).

objek: Persamaan: bit-wise equality ==: reference equality

string: (sama dengan dan == sama untuk string, tetapi jika salah satu string berubah menjadi objek, maka hasil perbandingan akan berbeda) Persamaan: bit-wise equality ==: bit-wise equality

Lihat di sini untuk penjelasan lebih lanjut.

Will Yu
sumber
Objek. Persamaan tidak harus melihat persamaan bitwise. Ini adalah metode virtual, dan override dapat melakukan apa pun yang diinginkannya.
phoog
ya, Anda benar, Anda dapat melakukan apa pun yang Anda inginkan untuk menimpanya. tetapi topik yang kita bicarakan adalah implementasi standar. implementasi standar Object.Equals adalah kesetaraan bit-wise.
Will Yu