Вся ситуация неприятная. В C# слишком много способов выразить равенство и неравенство:
- операторы == != > ‹ >= ‹= (которые являются логически статическими методами)
- статический метод Equals (который вызывает виртуальный метод), виртуальный метод Equals, метод ReferenceEquals
- Интерфейсы IComparable и IEquatable
Все они имеют немного разную семантику, и, за исключением статического Equals, ни один из них не использует автоматически другой, и ни один из них на самом деле не имеет нужного мне поведения. Статические методы отправляются на основе типа времени компиляции обоих операндов; виртуальные методы/методы интерфейса отправляются на основе типа времени выполнения одного из операндов, что делает операцию асимметричной; тип одной стороны имеет большее значение, чем тип другой.
Я не могу себе представить, чтобы кто-то думал, что положение, в котором мы находимся, прекрасно; при отсутствии ограничений это не то, что могло бы развиться. Но у разработчиков управляемых языков есть ограничения: CLR не реализует статические методы в контрактах интерфейса или двойную виртуальную диспетчеризацию, или возможность наложить ограничение оператора на параметр универсального типа. И поэтому появилось множество решений для решения проблемы равенства/неравенства.
Я думаю, что если бы разработчики CLR и C# вернулись в прошлое и рассказали себе в прошлом, какие функции должны быть в версии 1 CLR, некоторые формы статических методов в интерфейсах были бы первыми в списке. Если бы в интерфейсе были статические методы, то мы могли бы определить:
interface IComparable<in T, in U>
{
static bool operator <(T t, U u);
static bool operator >(T t, U u);
... etc
И тогда, если у вас есть:
static void Sort<T>(T[] array) where T : IComparable<T, T>
Затем вы можете использовать операторы <
и ==
и так далее для сравнения элементов.
person
Eric Lippert
schedule
15.12.2013
Compare(A, B)
, вы звонитеA.CompareTo(B)
. И это означает, что он никогда не сможет работать, еслиA
равноnull
, что вы можете захотеть поддерживать с помощью перегруженного оператора (x == null
иnull == x
должны проверять одно и то же). Я вовсе не уверен, что это основная причина. - person   schedule 15.12.2013