Почему С# 7 ValueTuples реализует метод Equals, но не оператор double equals?

Рассмотрим следующий фрагмент кода:

var tuple1 = (7, "foo");
var tuple2 = (7, "foo");
var tuple3 = (42, "bar");

Assert.That(tuple1.Equals(tuple2), Is.True);    //This passes
Assert.That(tuple1.Equals(tuple3), Is.False);   //This passes

Assert.That(tuple1 == tuple2, Is.True);         //This does not compile

Первые два утверждения проходят. Третий не компилируется.

Почему ValueTuple реализует собственный метод Equals, но не реализует оператор double equals?

Ответ 1

Оператор == не реализуется в библиотеке из-за противоречивых требований. Для всех x и y, которые правильно реализуют object.Equals (даже если они оставляют его как ссылочное сравнение), данный var tuple1 = (x, y); var tuple2 = (x, y);, tuple1.Equals(tuple2) равен true. Но tuple1 == tuple2, если оно реализовано, должно быть эквивалентно x == x && y == y, опять же, если оно реализовано. Последнее не всегда верно. В частности, это false, если x или y - double.NaN. Вот почему отклонен запрос на растяжение, добавив operator == в ValueTuple.

Реализация == в компиляторе, где это будет работать, только если элементы сравнения поддержки кортежа через ==, открытое предложение для компилятора, но просто еще не реализован. Там не так много активности, сейчас нет причины, почему она не будет реализована, но она просто не имеет высокого приоритета.