Не может ли оператор == быть применен к универсальным типам в C #? - PullRequest
298 голосов
/ 24 декабря 2008

Согласно документации оператора == в MSDN ,

Для предопределенных типов значений Оператор равенства (==) возвращает true, если значения его операндов равны, ложь в противном случае. Для справочных типов кроме строки, == возвращает true, если два его операнда относятся к одному и тому же объект. Для типа строки == сравнивает значения строк. Пользовательские типы значений могут перегружаться оператор == (см. оператор). Так может пользовательские ссылочные типы, хотя по умолчанию == ведет себя как описано выше для предопределенных и пользовательские ссылочные типы.

Так почему этот фрагмент кода не компилируется?

bool Compare<T>(T x, T y) { return x == y; }

Я получаю сообщение об ошибке Оператор '==' не может быть применен к операндам типа 'T' и 'T' . Интересно почему, поскольку, насколько я понимаю, оператор == предопределен для всех типов?

Редактировать: Спасибо всем. Сначала я не заметил, что утверждение касается только ссылочных типов. Я также подумал, что побитовое сравнение предоставляется для всех типов значений, которые, как я теперь знаю, не правильно.

Но если я использую ссылочный тип, будет ли оператор == использовать предопределенное сравнение ссылок, или он будет использовать перегруженную версию оператора, если определен тип?

Редактировать 2: Методом проб и ошибок мы узнали, что оператор == будет использовать предопределенное эталонное сравнение при использовании неограниченного универсального типа. Фактически, компилятор будет использовать лучший метод, который он может найти для аргумента ограниченного типа, но не будет искать дальше. Например, приведенный ниже код всегда будет печатать true, даже когда вызывается Test.test<B>(new B(), new B()):

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

Ответы [ 11 ]

1 голос
/ 24 декабря 2008

bool Compare(T x, T y) where T : class { return x == y; }

Выше будет работать, потому что == позаботился в случае пользовательских типов ссылок.
В случае типов значений == может быть переопределено. В этом случае также должно быть определено "! =".

Я думаю, что это может быть причиной, поэтому запрещает общее сравнение, используя "==".

...