Zgodnie z dokumentacją ==
operatora w MSDN ,
W przypadku predefiniowanych typów wartości operator równości (==) zwraca wartość true, jeśli wartości jego argumentów są równe, w przeciwnym razie false. W przypadku typów odwołań innych niż łańcuch == zwraca wartość true, jeśli dwa operandy odnoszą się do tego samego obiektu. Dla typu ciągu == porównuje wartości ciągów. Zdefiniowane przez użytkownika typy wartości mogą przeciążać operatora == (patrz operator). Podobnie mogą być typy referencyjne zdefiniowane przez użytkownika, chociaż domyślnie == zachowuje się tak, jak opisano powyżej, zarówno dla typów predefiniowanych, jak i zdefiniowanych przez użytkownika.
Dlaczego więc ten fragment kodu się nie kompiluje?
bool Compare<T>(T x, T y) { return x == y; }
Pojawia się błąd Operator „==” nie może być stosowany do operandów typu „T” i „T” . Zastanawiam się, dlaczego, skoro o ile rozumiem, ==
operator jest predefiniowany dla wszystkich typów?
Edycja: Dzięki wszystkim. Z początku nie zauważyłem, że stwierdzenie dotyczy tylko typów referencji. Pomyślałem też, że porównanie bit po bicie jest dla wszystkich typów wartości, co wiem teraz jest nie poprawny.
Ale w przypadku, gdy korzystam z typu odniesienia, czy ==
operator użyłby wstępnie zdefiniowanego porównania odniesienia, czy użyłby przeciążonej wersji operatora, jeśli typ byłby zdefiniowany?
Edycja 2: Dzięki próbom i błędom dowiedzieliśmy się, że ==
operator użyje predefiniowanego porównania referencyjnego, gdy użyje nieograniczonego typu ogólnego. Właściwie kompilator użyje najlepszej metody, jaką może znaleźć dla argumentu typu ograniczonego, ale nie będzie dalej szukał. Na przykład poniższy kod zawsze będzie drukowany true
, nawet gdy Test.test<B>(new B(), new B())
zostanie wywołany:
class A { public static bool operator==(A x, A y) { return true; } }
class B : A { public static bool operator==(B x, B y) { return false; } }
class Test { void test<T>(T a, T b) where T : A { Console.WriteLine(a == b); } }
==
nie można używać dwóch operandów tego samego typu. Dotyczy to struct
typów (z wyjątkiem typów „predefiniowanych”), które nie przeciążają operator ==
. Jako prosty przykład spróbuj tego:var map = typeof(string).GetInterfaceMap(typeof(ICloneable)); Console.WriteLine(map == map); /* compile-time error */
var kvp1 = new KeyValuePair<int, int>(); var kvp2 = kvp1;
, nie można sprawdzić, kvp1 == kvp2
ponieważ KeyValuePair<,>
jest strukturą, nie jest typem wstępnie zdefiniowanym w języku C # i nie powoduje przeciążenia operator ==
. Podany jest jednak przykład, za var li = new List<int>(); var e1 = li.GetEnumerator(); var e2 = e1;
pomocą którego nie można tego zrobić e1 == e2
(tutaj mamy zagnieżdżoną strukturę List<>.Enumerator
(wywoływaną "List`1+Enumerator[T]"
przez środowisko wykonawcze), która się nie przeciąża ==
).
bool
z void
...