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?
==
, tetapi operator tidak polimorfik. Dalam kode ini,==
operator dipanggil pada tipeobject
, yang melakukan perbandingan identitas daripada nilai satu.==
kelebihan berdasarkan pada jenis waktu kompilasi operan. TheContent
propertiobject
. Operator tidak virtual, sehingga implementasi standar==
disebut, memberikan referensi kesetaraan referensi. Dengan Equals, panggilan masuk ke metode virtualobject.Equals(object)
;string
mengganti 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 .==
memiliki tipe waktu kompilasiobject
dan sisi kanan memiliki tipe waktu kompilasistring
, maka kompiler C # harus memilih (bermasalah, dalam hal ini) kelebihan bebanoperator ==(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 kestring
. Jika saya ingat dengan benar, teks peringatan menyarankan hal itu.Jawaban:
Ketika
==
digunakan pada ekspresi tipeobject
, itu akan berubah menjadiSystem.Object.ReferenceEquals
.Equals
hanyalah sebuahvirtual
metode dan berperilaku seperti itu, sehingga versi yang diganti akan digunakan (yang, untukstring
tipe membandingkan konten).sumber
object
ketik (perhatikan font monospace) secara teknis dimaksudkan sebagai "ekspresi tipeSystem.Object
". Itu tidak ada hubungannya dengan jenis runtime dari instance yang disebut oleh ekspresi. Saya pikir pernyataan "operator yang ditetapkan pengguna diperlakukan sepertivirtual
metode" 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 berlebihvirtual
resolusi 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.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),
Equals
membandingkan 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:Outputnya adalah:
sumber
==
dan.Equals
keduanya 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.Equals
pada suatu objek tetapi mengabaikan untuk mengimplementasikan operator==
. Ini berarti bahwa.Equals
sebenarnya 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
Object.ReferenceEquals
langsung (tidak diperlukan dalam kasus umum)EqualityComparer<T>.Default
Dalam beberapa kasus ketika saya merasa penggunaan
==
ambigu saya secara eksplisit akan menggunakanObject.Reference
equals 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
sumber
== Operator
. Sama dengan
sumber
==
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 untukEquals
dengan komplikasi tambahan bahwa itu adalah metode virtual, sehingga perilakunya dapat diganti serta kelebihan beban.Pertama, ada adalah perbedaan. Untuk angka
Dan untuk string
Dalam kedua kasus,
==
berperilaku lebih bermanfaat daripada.Equals
sumber
==
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 afloat
dengan sesuatu selain darifloat
, ataudouble
dengan sesuatu selain daridouble
, menurut saya sebagai bau kode utama yang tidak boleh dikompilasi tanpa diagnostik.x == y
tidak menyiratkanx/3 == y/3
(cobax = 5
dany = 5.0
)./
untuk divisi integer menjadi cacat dalam desain C # dan Java. Pascaldiv
dan bahkan VB.NET's` are much better. The problems with
== `lebih buruk, meskipun:x==y
dany==z
tidak menyiratkan itux==z
(pertimbangkan tiga angka dalam komentar saya sebelumnya). Adapun hubungan yang Anda sarankan, bahkan jikax
dany
keduanyafloat
atau keduanyadouble
,x.equals((Object)y)
tidak menyiratkan bahwa1.0f/x ==
1.0f / y` (jika saya memiliki druthers saya, itu akan menjamin bahwa; bahkan jika==
tidak membedakan positif dan nol,Equals
seharusnya).Sejauh yang saya mengerti jawabannya sederhana:
==
membandingkan referensi objek..Equals
membandingkan konten objek.String
tipe data selalu bertindak seperti perbandingan konten.Saya harap saya benar dan itu menjawab pertanyaan Anda.
sumber
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:
sumber
object expr = XXX; if (expr == "Energy") { ... }
, maka karena sisi kiri adalah tipe waktu kompilasiobject
, kompiler harus menggunakan kelebihan bebanoperator ==(object, object)
. Ini memeriksa kesetaraan referensi. Apakah itu akan memberitrue
ataufalse
sulit diprediksi karena string magang . Jika Anda tahu sisi kirinull
jenis atau tipenyastring
, lemparkan ke sisi kiristring
sebelum digunakan==
.Karena versi statis dari
.Equal
metode ini tidak disebutkan sejauh ini, saya ingin menambahkan ini di sini untuk meringkas dan membandingkan 3 variasi.di mana
MyString
variabel 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.Equals
saat 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.Memang sedikit lebih untuk menulis, tetapi menurut saya, lebih aman digunakan.
Berikut ini beberapa info yang disalin dari Microsoft:
Parameter
a
TaliString pertama yang dibandingkan, atau
null
.b
TaliString kedua untuk membandingkan, atau
null
.Kembali
Boolean
true
jika nilaia
sama dengan nilaib
; jika tidakfalse
,. Jika keduanyaa
danb
ininull
, metode kembalitrue
.sumber
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
sumber
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.
sumber
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
string
nilainya. Menggambarkan:Outputnya adalah:
sumber
Menambahkan satu poin lagi ke jawabannya.
.EqualsTo()
Metode memberi Anda ketentuan untuk membandingkan dengan budaya dan case sensitif.sumber
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, danIs
digunakan sebagai operator uji-referensi atau null-test. Suatu untuk digunakan=
pada suatu tipe yang tidak mengesampingkan operator pemeriksa kesetaraan akan gagal, sebagaimana akan berusaha digunakanIs
untuk 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,
int
dapat memiliki (dan IMHO seharusnya tetapi tidak) mendefinisikan operator kesetaraan untuk perbandinganfloat
, sehingga 16777217 tidak akan melaporkan dirinya sama dengan 16777216f. Karena, karena tidak ada operator yang didefinisikan, C # akan mempromosikanint
kefloat
, 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.sumber
3
sebagai sama dengan3.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.Jawaban dan contoh yang sangat bagus!
Saya hanya ingin menambahkan perbedaan mendasar antara keduanya,
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 .
sumber
Ketika kita membuat objek apa pun ada dua bagian untuk objek yang satu adalah konten dan yang lainnya adalah referensi untuk konten itu.
==
membandingkan konten dan referensi;equals()
hanya membandingkan kontenhttp://www.codeproject.com/Articles/584128/Apa-adalah-perbedaan- antara antara-samaandengan-dan-Eq
sumber
a
danb
keduanya adalah referensi string, maka hasil daria == b
tidak bergantung pada apakah referensi menunjuk ke objek yang sama.==
Operator == dapat digunakan untuk membandingkan dua variabel apa pun, dan itu hanya membandingkan bit .
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.
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"
sumber
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.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.
sumber