Почему оператор == работает для Nullable, когда == не определен?

Я только что просматривал этот ответ, который содержит код для Nullable из .NET Reflector, и заметил две вещи:

  1. При переходе от Nullable к T требуется явное преобразование.
  2. Оператор == не определен.

Учитывая эти два факта, меня удивляет, что это компилируется:

int? value = 10;
Assert.IsTrue(value == 10);

С кодом value == 10, либо value волшебным образом преобразуется в int (что позволяет использовать оператор int ==, или оператор == волшебным образом определяется для Nullable. (Или, что менее вероятно, Reflector опускает часть кода).

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

Assert.IsTrue((value.Equals(10)); // works because Equals *is* defined
Assert.IsTrue(value.Value == 10); // works because == is defined for int
Assert.IsTrue((int?)value == 10); // works because of the explicit conversion

Они, конечно, работают, но == тоже работает, и это та часть, которую я не понимаю.

Причина, по которой я это заметил и задаю этот вопрос, заключается в том, что я пытаюсь написать структуру, которая работает примерно так же, как Nullable. Я начал с кода Reflector, ссылка на который приведена выше, и просто сделал несколько очень незначительных модификаций. К сожалению, мой CustomNullable не работает так же. Я не могу выполнить Assert.IsTrue(value == 10). Я получаю "Operator == cannot be applied to operands of type CustomNullable and int".

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

CustomNullable value = null;

... потому что я понимаю, что за Nullable стоит какая-то магия компилятора, которая позволяет устанавливать значения в null, даже если Nullable является структурой, но я ожидал бы, что я смогу имитировать все другие поведения Nullable, если мой код написан (почти) идентично.

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

12
задан Community 23 May 2017 в 12:32
поделиться