== ve Eşittir () arasındaki C # farkı


548

Ben kullandığınızda nedense 2 dizeleri karşılaştıran bir Silverlight uygulamasında bir şartım var ==döndürür false iken .Equals()döner doğrudur .

İşte kod:

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

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

Bunun neden olduğuna dair bir sebep var mı?



8
Dize geçersiz kılınır ==, ancak işleçler polimorfik değildir. Bu kodda, ==işleç, objectbir değer yerine kimlik karşılaştırması yapan türde çağrılır .
Drew Noakes

12
@DrewNoakes'un yorumunu genişletmek için: Derleyici ==, işlenenlerin derleme zamanı türüne göre bir aşırı yük seçer . ContentÖzelliktir object. İşleçler sanal değildir, bu nedenle varsayılan ==eşit uygulaması çağrılır ve referans eşitliği karşılaştırması sağlanır. Eşittir ile çağrı sanal yönteme gider object.Equals(object); stringbu yöntemi geçersiz kılar ve dize içeriği üzerinde sıralı bir karşılaştırma yapar. Bkz. Msdn.microsoft.com/en-us/library/fkfd9eh8(v=vs.110).aspx ve referenceource.microsoft.com/#mscorlib/system/string.cs,507 .
Phoog

6
@ phoog'un açıklaması kesin. Unutulmamalıdır ki, sol tarafının ==derleme zamanı türü objectve sağ tarafın derleme zamanı türü olduğunda string, C # derleyicisi (bu durumda sorunlu) aşırı yükü seçmelidir operator ==(object, object); ama olacak o da kasıtlı olmayan edilebileceğini derleme zamanı uyarıda. Yani okunan derleme zamanı uyarıları! Sorunu çözmek ve hala kullanmak ==için sol tarafı şuraya yayınlayın string. Doğru hatırlarsam, uyarı metni bunu önerir.
Jeppe Stig Nielsen

1
Derleyici uyarılarını okuma önerisi için @JeppeStigNielsen +1. Daha da iyisi: herkesi onlara dikkat etmeye zorlamak için hata olarak uyar seçeneğini etkinleştirin.
phoog

Yanıtlar:


429

Bir ==tür ifadesinde kullanıldığında, objectçözümlenir System.Object.ReferenceEquals.

Equalsyalnızca bir virtualyöntemdir ve böyle davranır, bu nedenle geçersiz kılınan sürüm kullanılır (bu, stringtür için içeriği karşılaştırır).


56
Operatör sınıfta özel olarak uygulanmadıkça
Dominic Cronin

23
@DominicCronin Bu doğru değil. == sınıfta uygulansa bile, karşılaştırmanın solundaki tür nesne olduğundan yok sayılır. Operatör aşırı yüklerinin derleme zamanında ve derleme zamanında belirlendiği anlaşılmaktadır, tek bildiği sol tarafın bir nesne olmasıdır.
MikeKulls

4
@DominicCronin İlk ifadenizin doğru olduğuna inanıyorum. Oldukça farklıdırlar.
MikeKulls

8
Açık olmak gerekirse, objectyazın (tek aralıklı yazı tipine dikkat edin) teknik olarak "tür ifadesi" anlamına gelir System.Object. İfadenin başvurduğu örneğin çalışma zamanı türüyle hiçbir ilgisi yoktur. "Kullanıcı tanımlı işleçlere virtualyöntem gibi davranılıyor" ifadesinin son derece yanıltıcı olduğunu düşünüyorum. Aşırı yüklenmiş yöntemler gibi davranılır ve yalnızca işlenenlerin derleme zamanı türüne bağlıdır. Aslında, aday kullanıcı tanımlı operatörler kümesi hesaplandıktan sonra, bağlama prosedürünün geri kalanı tam olarak yöntem aşırı yük çözümleme algoritması olacaktır
Mehrdad Afshari

4
@DominicCronin Yanıltıcı kısım, virtualyöntem çözünürlüğünün bir örneğin gerçek çalışma zamanı türüne bağlı olmasıdır, oysa bu, operatör aşırı yük çözünürlüğünde tamamen yok sayılır ve gerçekten de cevabımın bütün noktasıdır.
Mehrdad Afshari

314

Bir nesne başvurusunu bir dizeyle karşılaştırırken (nesne başvurusu bir dizeye başvursa bile), ==dize sınıfına özgü operatörün özel davranışı yok sayılır.

(Olup dizeleri ile ilgili değildir) normal olarak, Equalskarşılaştırır değerleri ise, ==karşılaştırır nesne referanslar . Karşılaştırdığınız iki nesne bir nesnenin tam olarak aynı örneğine başvuruyorsa, her ikisi de true değerini döndürür, ancak biri aynı içeriğe sahipse ve farklı bir kaynaktan geliyorsa (aynı verilere sahip ayrı bir örnekse), yalnızca Eşittir doğru dön. Bununla birlikte, yorumlarda belirtildiği gibi, dize özel bir durumdur, çünkü ==operatörü geçersiz kılar, böylece yalnızca dize referanslarıyla (nesne referanslarıyla değil) uğraşırken, yalnızca ayrı örnekler olsalar bile değerler karşılaştırılır. Aşağıdaki kod, davranışlardaki küçük farklılıkları göstermektedir:

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));

Çıktı:

True True True
False True True
False False True

8
Açık. '==' işleci nesne başvurularını (sığ karşılaştırma) karşılaştırırken .Equals () nesne içeriğini (derin karşılaştırma) karşılaştırır. @Mehrdad'ın dediği gibi, bu derin içerik karşılaştırmasını sağlamak için .Equals () geçersiz kılınır.
Andrew

1
Gönderiyi burada bırakacağım, çünkü gerçekleşmemeye çok dikkat etmeniz gerektiğinden, olmayanları vurgulamanın değerli olduğunu düşünüyorum. (Ve doğru ve yanlış anlamaları göstermek için kodun da değerli olduğunu düşünüyorum.) Umarım derecelendirme 0'ın altına
düşmez

5
Elbette String özel bir == işleci uygular. O zaman == kullanmak içeriği karşılaştırmak olmazdı. Bu nedenle, String, burada kullanmak için kötü bir örnektir, çünkü özel bir operatörün tanımlanmadığı genel durumu anlamamıza yardımcı olmaz.
Dominic Cronin

6
Epik kod örneği için +1, bu beni anlamlandırdı. Nesne olan statik türün (Sol Taraf tipi) genel durumunu ve dizge olan statik türün (/ RHS türü) özel durumunu gösterir. Ve dizi stajyerine iyi dokunur.
barlop

2
@badsamaritan String interning nedeniyle
Alexander Derck

46

==ve .Equalsher ikisi de gerçek sitede tanımlanan davranışa ve çağrı sitesindeki gerçek türe bağlıdır. Her ikisi de sadece herhangi bir türde geçersiz kılınabilen ve yazarın istediği herhangi bir davranışta bulunabilecek yöntem / işleçlerdir. Deneyimlerime göre, insanların .Equalsbir nesne üzerinde uygulama yapmasının yaygın olduğunu , ancak operatörü uygulamayı ihmal ettiğini görüyorum ==. Bu .Equals, aslında değerlerin eşitliğini ==ölçecek, aynı referans olup olmadıklarını ölçecek demektir.

Tanımı akı içinde olan veya genel algoritmalar yazan yeni bir türle çalışırken, en iyi uygulamanın aşağıdaki olduğunu düşünüyorum

  • C # referansları karşılaştırmak istiyorsanız, Object.ReferenceEqualsdoğrudan kullanın (genel durumda gerekli değildir)
  • Eğer kullandığım değerleri karşılaştırmak istersem EqualityComparer<T>.Default

Bazı durumlarda kullanımın ==belirsiz olduğunu düşündüğümde , belirsizliği Object.Referencekaldırmak için açıkça koddaki eşitleri kullanacağım .

Eric Lippert yakın zamanda CLR'de neden 2 eşitlik yöntemi olduğu konusunda bir blog yazısı yaptı. Okumaya değer


Jared, doğrudan Jeff'in meşhur “En iyi kod hiç kod değil” dir. Bu gerçekten haklı mı? Öte yandan, bunun nereden kaynaklandığını ve anlambilimin açık hale getirilmesinin neden istenebileceğini görebiliyorum. Bu durumda, VB'nin nesne eşitliği ile uğraşma şeklini çok tercih ediyorum. Kısa ve açık.
Konrad Rudolph

@Konrad, "bir tipe aşina olmadığımda, en iyi uygulamanın aşağıdaki olduğunu düşünüyorum" demeliydim. Evet VB burada çok daha iyi anlambilime sahiptir çünkü değer ve referans eşitliğini gerçekten ayırır. C #, ikisini birlikte karıştırır ve bazen belirsizlik hatalarına neden olur.
JaredPar

10
Bu tamamen doğru değil. == geçersiz kılınamaz, statik bir yöntemdir. Sadece aşırı yüklenebilir, bu da önemli bir farktır. Bu nedenle, == işleci için yürütülen kod derleme zamanında bağlanırken, Equals sanaldır ve yürütme zamanında bulunur.
Stefan Steinegger

20

== Operatör

  1. İşlenenler Değer Türleri ve değerleri eşitse, başka true değerini döndürür.
  2. İşlenenler dize dışında Referans Türleriyse ve her ikisi de aynı örneğe (aynı nesne) başvuruyorsa , başka true değerini döndürür.
  3. İşlenenler dize türüyse ve değerleri eşitse, başka true değerini döndürür.

.Equals

  1. İşlenenler Referans Türleri ise, her ikisi de aynı örneğe (aynı nesneye) başvuruyorsa, Referans Eşitliği gerçekleştirir , aksi halde true değerini döndürür.
  2. İşlenenler ise değer Türleri == operatörü aksine sonra kendi için denetler tip birinci ve onların türleri eğer başka aynı gerçekleştirdiği == operatörü yanlış döndürür vardır.

2
Bu doğru değil. ==Operatör her tür değil, sadece dize için aşırı yüklenebilir. Özel bir özel durum istisnasını yalnızca dize için tanımlamak, operatörün anlamını temsil eder. Belki de çok yararlı olmasa da, "işlenenler referans türleri ise, işlenenler aynı nesneye başvuruyorsa, geçerli bir aşırı yük yoksa, bu aşırı yükün uygulanması sonucu belirlerse doğru döner. ". Aynı şey Equals, sanal bir yöntem olduğu eklenen karmaşıklık için de geçerlidir , bu nedenle davranışı geçersiz kılmanın yanı sıra aşırı yüklenebilir.
Phoog

19

İlk olarak, var olan bir fark. Sayılar için

> 2 == 2.0
True

> 2.Equals(2.0)
False

Ve dizeler için

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

> x.Equals(null)
NullReferenceException

Her iki durumda da, ==daha yararlı daha davranır.Equals


2
İntegral tiplerin kayan nokta tiplerine olan zorlamasını ==operatörle birlikte iyi bir şey olarak göreceğime emin değilim . Örneğin, 16777216.0f (int) 16777217, (çift) 16777217.0'a eşit veya her ikisi birden eşit mi? İntegral tipler arasındaki karşılaştırmalar iyidir, ancak kayan nokta karşılaştırmaları IMHO'nun yalnızca eşleşen türlere açıkça atanan değerlerle gerçekleştirilmesi gerekir. Bir karşılaştırılması floatbir dışında bir floatya da doublebir başka şeye double, teşhis olmadan derlemek olmamalıdır büyük bir kod koku gibi geliyor bana.
supercat

1
@supercat katılıyorum — bu x == yima etmeyen üzücü x/3 == y/3(denemek x = 5ve y = 5.0).
Albay Panik

Ben /tamsayı bölümü kullanımı C # ve Java tasarımında bir kusur olarak düşünün . Pascal'ın divve hatta VB.NET'in ` are much better. The problems with == `daha da kötüsü: x==yve y==zbunu ima etmiyor x==z(önceki yorumumdaki üç sayıyı düşünün). Eğer bile önermek ilişkisi gelince xve yher ikisi floatveya her ikisi double, x.equals((Object)y)anlamına gelmez 1.0f/x == 1.0f / y` (benim druthers olsaydı, o kadar güvence altına alacağını; bile ==, pozitif ayrım ve sıfır gelmez Equalsolmalıdır).
supercat

Bu normaldir, çünkü Equals () 'in ilk parametresi bir dizedir!
Whiplash

17

Anladığım kadarıyla cevap basit:

  1. == nesne referanslarını karşılaştırır.
  2. .Equals nesne içeriğini karşılaştırır.
  3. String veri türleri her zaman içerik karşılaştırması gibi davranır.

Umarım doğruyum ve sorunuzu cevaplamıştır.


15

Nesnenizi bir dizeye yayınlarsanız, düzgün çalışacağını ekleyeceğim. Bu yüzden derleyici size bir uyarı verecektir:

Olası istenmeyen referans karşılaştırması; değer karşılaştırması almak için sol tarafa 'dize' yazın


1
Kesinlikle. @DominicCronin: Her zaman derleme zamanı uyarılarına uyun. Eğer varsa object expr = XXX; if (expr == "Energy") { ... }, sol taraf derleme zamanı tipinde objectolduğundan, derleyici aşırı yükü kullanmalıdır operator ==(object, object). Referans eşitliğini kontrol eder. O verecektir olsun trueya falsenedeniyle tahmin etmek zor olabilir dize interning . Sol tarafın ya da tipte olduğunu biliyorsanız , kullanmadan önce sol tarafın üzerine dökün . nullstringstring==
Jeppe Stig Nielsen

başka bir yolunu koymak. == (referans eşitliği mi yoksa değer eşitliği mi kullanacağının belirlenmesinde) derleme zamanı tipine / statik tipe / sol taraf tipine bağlıdır. (derleme zamanı analizinde çözülen tür budur). Çalışma zamanı türü / dinamik türü / RHS türü yerine. BlueMonkMN'nin kodu dökümle olmasa da bunu gösteriyor.
barlop

5

.EqualYöntemin statik sürümü şu ana kadar bahsedilmediğinden, bunu 3 varyasyonu özetlemek ve karşılaştırmak için buraya eklemek istiyorum.

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

Burada MyString, kodda başka bir yerden gelen bir değişken vardır.

Arka plan bilgisi ve yaza göre:

Java'da ==dizeleri karşılaştırmak için kullanılmamalıdır. Her iki dili de kullanmanız gerektiğinde ve ayrıca ==C # 'da kullanmanın daha iyi bir şeyle değiştirilebileceğini bildirmek için bunu belirtmiştim .

C # 'da, her ikisi de tür dizgisi olduğu sürece, Yöntem 1 veya Yöntem 2'yi kullanarak dizeleri karşılaştırmak için pratik bir fark yoktur. Bununla birlikte, biri boşsa, biri başka bir türdeyse (tamsayı gibi) ya da biri farklı bir referansa sahip bir nesneyi temsil eder, o zaman, ilk sorunun gösterdiği gibi, içeriği eşitlik için karşılaştırmanın neyi döndürmeyebileceğini deneyimleyebilirsiniz bekliyoruz.

Önerilen çözüm:

Kullanmak ==, .Equalsşeyleri karşılaştırırken kullanmakla tam olarak aynı olmadığından , bunun yerine statik String.Equals yöntemini kullanabilirsiniz . Bu şekilde, iki taraf aynı tür değilse, içeriği yine de karşılaştıracaksınız ve biri boşsa, istisnayı önleyeceksiniz.

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

Yazmak biraz daha fazla, ama bence kullanmak daha güvenli.

Microsoft'tan kopyalanan bazı bilgiler:

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

Parametreler

a sicim

Karşılaştırılacak ilk dize veya null.

b sicim

Karşılaştırılacak ikinci dize veya null.

İadeler Boolean

truedeğeri, değeri ile aaynı ise b; aksi takdirde false. Hem ave hem bde null, yöntem döndürülür true.


5

Zaten iyi yanıtlara ek olarak: Bu davranış Dizelerle veya farklı sayı türlerini karşılaştırmakla sınırlı DEĞİLDİR. Her iki öğe de aynı altta yatan türde bir nesne olsa bile. "==" çalışmaz.

Aşağıdaki ekran görüntüsü iki nesne {int} - değerinin karşılaştırılmasının sonuçlarını göstermektedir

VS2017 Örneği


2

Burada biraz kafam karıştı. İçeriğin çalışma zamanı türü dize türündeyse, hem == hem de Equals doğru dönmelidir. Ancak, bu durum böyle görünmediğinden, çalışma zamanı İçerik türü dize değildir ve buna eşittir çağrısı referans eşitliği yapıyor ve bu da Eşittir ("Enerji Saldırısı") neden başarısız olduğunu açıklıyor. Ancak, ikinci durumda, aşırı yüklenmiş == statik operatörün çağrılması gerektiği karar derleme zamanında verilir ve bu karar == (dize, dize) olarak görünür. bu bana Content'in dizeye örtük bir dönüşüm sağladığını gösterir.


2
Önden geri döndün. Bir başlangıç ​​için Eşittir ("Enerji Saldırısı") başarısız olmaz, == false değerini döndürür. == başarısız olur çünkü == dizeden değil, nesneden kullanılır.
MikeKulls

Varsayılan olarak, operatör == iki referansın aynı nesneyi gösterip göstermediğini belirleyerek referans eşitliğini test eder. Bu nedenle, bu işlevsellik kazanmak için başvuru türlerinin işleç == uygulaması gerekmez. Bir tür değiştirilemez olduğunda, yani, örnekte yer alan veriler değiştirilemez, referans eşitliği yerine değer eşitliğini karşılaştırmak için aşırı yük operatörü == yararlı olabilir çünkü değişmez nesneler olarak, uzun süre aynı kabul edilebilirler. aynı değere sahip oldukları için. Değişmez tiplerde operatörü == geçersiz kılmak iyi bir fikir değildir.
Wajeed-MSFT

2

@BlueMonkMN'nin daha önceki bir cevabının başka bir boyutu daha var. Ek boyut, @ Drahcir'in başlık sorusunun belirtildiği gibi cevabının , değere nasıl ulaştığımıza da bağlı olmasıdır string. Örneklemek gerekirse:

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));

Çıktı:

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

2

Cevaba bir puan daha eklemek.

.EqualsTo() yöntemi, kültüre ve büyük / küçük harfe duyarlı olmanızı sağlar.


0

==C # içindeki simge iki farklı eşitlik denetimi operatörü için kullanılır. Derleyici bu simgeyle karşılaştığında, karşılaştırılan türlerden birinin, karşılaştırılan belirli kombinasyon türleri (*) veya her iki türün dönüştürülebileceği türlerin bir kombinasyonu için eşitlik-operatör aşırı yükü uygulayıp uygulamadığını kontrol eder. Derleyici böyle bir aşırı yük bulursa kullanır. Aksi takdirde, her iki tür de referans türüyse ve ilgisiz sınıflar değilse (bir arabirim olabilir veya ilgili sınıflar olabilir), derleyici ==bir referans karşılaştırma operatörü olarak kabul edilir. Her iki koşul da geçerli değilse derleme başarısız olur.

Diğer bazı dillerin iki eşitlik denetimi operatörü için ayrı jetonlar kullandığını unutmayın. Örneğin, VB.NET'te, =jeton ifadeler içinde yalnızca yüklenebilir eşitlik denetimi operatörü Isiçin kullanılır ve bir referans testi veya null testi operatörü olarak kullanılır. =Eşitlik denetimi operatörünü geçersiz kılmayan bir türdeki bir kullanım , Isreferans eşitliğini veya geçersizliğini sınamak dışında herhangi bir amaç için kullanmaya çalışacağı gibi başarısız olur .

(*) Tipler genellikle kendileriyle karşılaştırma için sadece aşırı yük eşitliği, ancak tiplerin diğer belirli türlerle karşılaştırma için aşırı yük operatörüne aşırı yüklenmesi yararlı olabilir; örneğin, intkarşılaştırma için bir eşitlik işleçleri tanımlayabilirdi (ve IMHO'nun yapması gerekirdi, ama floattanımamamıştı), böylece 16777217 kendisini 16777216f'ye eşit olarak bildirmezdi. Olduğu gibi böyle bir operatör tanımlanmış olduğundan, C # teşvik edecektir intiçin floateşitlik-çek operatörü görmeden 16777216f bunu yuvarlama; bu operatör daha sonra iki eşit kayan noktalı sayı görür ve gerçekleşen yuvarlamadan habersiz olarak bunları eşit olarak bildirir.


Bir int-to-float karşılaştırması false döndürmektense, F # 'ın kullandığı yaklaşımı tercih ederim, bu tür bir karşılaştırmaya hiç izin vermemek. Daha sonra programcı, değerlerin farklı tipte olup olmadığı ve nasıl ele alınacağına karar verebilir. Bazen Çünkü sonuçta biz bunu tedavi etmek istiyorum 3eşit olarak 3.0f. Programcıdan her durumda neyin amaçlandığını söylemesini istiyorsak, varsayılan davranış olmadığından istenmeyen sonuçlara yol açan varsayılan davranış tehlikesi yoktur.
Phoog

@phoog: Benim kişisel duygularım, dillerin "normal" eşitlik testi araçlarına bir denklik ilişkisi uygulaması ve sahip olamayacakları tüm işlenen kombinasyonlarını yasaklaması gerektiğidir. Tamsayılar ve şamandıralar arasında bir dil kontrol eşitliğine sahip olmanın büyük bir avantaj görmüyorum, bir şamandıra, int ile eşleşen bir sayıyı tam olarak temsil ediyor, ancak bu tür karşılaştırmaları yasaklıyor, ancak her iki yaklaşımın da dilin gerçekleştirilmesinden daha üstün olduğunu düşünüyoruz karşılaştırma öncesi kayıplı bir dönüşüm.
Supercat

0

Gerçekten harika cevaplar ve örnekler!

Sadece ikisi arasındaki temel farkı eklemek istiyorum,

Gibi operatörler ==polimorfik değildir Equals,

Bu kavram göz önünde bulundurularak, herhangi bir örnek üzerinde çalışırsanız (sol el ve sağ el referans türüne bakarak ve türün gerçekten == operatör aşırı yüklendiğini ve Eşittir geçersiz kılındığını kontrol edip bilerek) doğru cevabı alacağınızdan emin olabilirsiniz. .


-1

Herhangi bir nesne oluşturduğumuzda, nesnenin biri içerik, diğeri ise o içeriğe referans yapan iki bölüm vardır. ==hem içeriği hem de referansı karşılaştırır; equals()sadece içeriği karşılaştırır

http://www.codeproject.com/Articles/584128/What-is-the-difference-between-equalsequals-and-Eq


1
Bu doğru değil. Eğer ave bikisi de dize referansları olan, daha sonra sonuç a == breferanslar aynı nesneye işaret edip etmediğine bağlı değildir.
Phoog

-2

==

== operatörü herhangi bir türdeki iki değişkeni karşılaştırmak için kullanılabilir ve sadece bitleri karşılaştırır .

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

Not: int'in sol tarafında daha fazla sıfır var, ancak burada bunu umursamıyoruz.

int a (00000011) == bayt b (00000011)

== operatörünün yalnızca değişken içindeki bitlerin modeline önem verdiğini unutmayın.

== İki başvuru (ilkeller) öbek üzerinde aynı nesneyi gösteriyorsa kullanın.

Değişken bir referans veya ilkel olsa da kurallar aynıdır.

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 doğru a == b yanlış

bit örüntüsü a ve c için aynıdır, bu nedenle == kullanarak eşittirler.

Eşit():

İki farklı nesnenin eşit olup olmadığını görmek için equals () yöntemini kullanın .

Her ikisi de "Jane" deki karakterleri temsil eden iki farklı String nesnesi gibi


2
Bu yanlış. Aşağıdakileri göz önünde bulundurun: object a = 3; object b = 3; Console.WriteLine(a == b);. Değerlerin bit örüntüleri aynı olsa bile çıktı yanlıştır. İşlenen türleri de önemlidir. Örneğinizdeki farklı sıfır sayısını "önemsemememizin" nedeni, eşit işleç dediğimizde, örtük dönüşüm nedeniyle sıfır sayısının aslında aynı olmasıdır.
Phoog

-2

Eşit ve == arasındaki tek fark nesne türü karşılaştırmasındadır. referans türleri ve değer türleri gibi diğer durumlarda, neredeyse aynıdırlar (her ikisi de bit-bilge eşitliği veya her ikisi de referans eşitliğidir).

object: Eşittir: bit-bilge eşitliği ==: referans eşitliği

string: (eşittir ve == dize için aynıdır, ancak dizeden biri nesneye değiştirilirse karşılaştırma sonucu farklı olur) Eşittir: bit-wise eşitliği ==: bit-wise eşitliği

Daha fazla açıklama için buraya bakın .


Object.Equals mutlaka bitsel eşitliğe bakmaz. Sanal bir yöntemdir ve geçersiz kılma istediği her şeyi yapabilir.
Phoog

evet haklısınız, geçersiz kılmak istediğiniz her şeyi yapabilirsiniz. ancak konuştuğumuz konu varsayılan uygulamadır. Object.Equals uygulamasının varsayılan uygulaması bit-bilge eşitliktir.
Yu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.