2009-04-30 19 views
15

w języku C# co dokładnie dzieje się w tle podczas porównywania z operatorem "==" na dwóch obiektach? czy po prostu porównuje adresy? czy to jest coś takiego jak Equals() lub CompareTo()?C# co robi operator ==?

PS: co z operatorem "==" w java? czy zachowuje się tak samo?

+0

Wystarczy szybkie info: jeśli przeciążać ==, należy również wdrożyć =!. To samo dotyczy <= and > =. – Tarik

Odpowiedz

24

O ile wiem:

  • porównuje typy wartości przez wartość (równość)
  • porównuje typy referencyjne przez odniesienie (tożsamość)
  • wyjątkiem przypadku, gdy operator == jest przeciążony, a następnie to się nazywa.

Równiki są zaimplementowane w obiekcie i można je również przesłonić. Domyślna implementacja w obiekcie wykonuje porównanie referencyjne dla typów referencyjnych. Więc domyślnie Równości i == robią to samo.

Myślę, że w java nie można przeciążać operatora ==. Ale moja wiedza Java jest dość przestarzała.

Edytuj: Należy zauważyć, że operator == jest metodą statyczną. Jest związany w czasie kompilacji, w oparciu o typy zmiennych lub pól. Equals to wirtualna metoda znaleziona w środowisku wykonawczym na podstawie rzeczywistych typów środowiska wykonawczego.

+3

Doskonała odpowiedź; przynajmniej jedno pominięcie, jednak: http://stackoverflow.com/questions/806020/snip/806068#806068 –

+0

nie można przesłonić operatora == w java, dla typów odniesienia w java == zawsze zrobi odwołanie (tożsamość) porównanie. –

+1

Nie można przesłonić operatorów w języku C#, ponieważ nie są one wirtualne. Możesz je tylko przeciążać. –

4

From MSDN:

Dla typów wartości predefiniowanych, operator równości (==) zwraca true jeśli wartości jego operandy są równe, false w przeciwnym wypadku. Dla typów odniesienia innych niż ciąg znaków, == zwraca wartość true, jeśli jej dwa operandy odnoszą się do tego samego obiektu . W przypadku typu łańcucha == porównuje wartości ciągów.

3

Nie ... operator == nie zawsze zachowuje się tak samo w java i C#.

Na przykład ze stringami; Java == porównuje odwołania do obiektów typu string ... (jeśli używasz typów primitve, == w java porównuje wartości). Dlatego

// returns FALSE in JAVA 
(new String("test") == "test") 

nie zwróci true w Java ...

W języku C# w przeciwieństwie do tego, operator == nie zachowują się inaczej na strunach. Na przykład, zwróci true w następującym przypadku:

// returns TRUE in C# 
(new String("test".ToCharArray()) == "test") 
+0

Dzieje się tak dlatego, że operator == nie może być nadpisany w Javie, ale w C# i to jest to, co jest dla łańcuchów. Czy to powoduje, że zachowanie operatora jest inne? –

+0

Myślę, że jest to typowa pułapka, gdy jesteś przyzwyczajony do pisania oprogramowania w języku C#, a następnie używania języka Java w innym projekcie ... dlatego chciałem wskazać to – Homes2001

9

Jako rozszerzenie do Stefan's excellent answer - kolejny Wyjątkiem jest jeśli operandy obejmować Nullable<T> - w tym przypadku „podnoszony” operatorzy stosują (14.2.7 ECMA 334v4):

dla operatorów równości == =

podniesionym forma operatora istnieje, jeżeli są oba typy argumentów operacji typy wartości dla wartości pustych i jeżeli typ skutek! jest bool. Podniesiona forma jest skonstruowana przez dodanie singla? modyfikator do każdego typu operandu. Operator podnoszący uważa dwie wartości zerowe za równe, a wartość pusta nierównomierną dla dowolnej wartości innej niż null. Jeśli oba operandy mają wartość inną niż null, operator unlapped operandów odwija ​​argumenty operacji i stosuje operatora bazowego do , powodując wynik bool.

co oznacza, że ​​jest: ponieważ nie jest operatorem równości (powiedzmy)

int i = ..., j = ...; 
bool eq = i == j; 

Zatem istnieje niejawna operator postaci (chociaż odbywa się inaczej):

int? i = ..., j = ...; 
bool eq; 
if(i.HasValue) { 
    if(j.HasValue) { // both have values; compare 
     eq = i.GetValueOrDefault() == j.GetValueOrDefault(); 
    } else { // one null; always false 
     eq = false; 
    } 
} else { // true if both null, else false 
    eq = !j.HasValue; 
} 
0

Zachowanie operatora == zależy od tego, w jaki sposób została zastosowana zmienna, do której go stosujesz (nie w klasie obiektu, dodam przykład).

Dla typów wartości porównuje ich wartości.

Dla typów odniesienia a == b zwraca wartość true, jeśli a jest tym samym obiektem co b, chyba że operator == był przeciążony. Nie można go przesłonić, jak powiedzieli inni, nie można przesłonić operatorów w języku C#, ponieważ nie są wirtualni.

object obj_a, obj_b; string str_a, str_b;

 str_a = "ABC"; 
     str_b = new string("ABC".ToCharArray()); 
     obj_a = str_a; 
     obj_b = str_b; 

     Console.WriteLine("str_a == str_b = {0}", str_a == str_b); // in string == operator is overloaded 
     Console.WriteLine("str_a.Equals(str_b) = {0}", str_a.Equals(str_b)); // string overrides Object.Euqals 
     Console.WriteLine("obj_a == obj_b = {0}", obj_a == obj_b); // in object == operator is not overloaded 
     Console.WriteLine("obj_a.Equals(obj_b) = {0}", obj_a.Equals(obj_b)); // Object.Equesl is virtual and overridden method from string will be executed. 
     Console.ReadKey(); 

Wyjście z tego programu jest

 
str_a == str_b = True 
str_a.Equals(str_b) = True 
obj_a == obj_b = False 
obj_a.Equals(obj_b) = True