Необнуляемое равенство DateTime (in) с нулевым компилируется и запускается? - PullRequest
1 голос
/ 30 сентября 2019

Исходя из этого вопроса , я (и ОП в указанном вопросе) запутался, когда этот фрагмент кода компилируется и запускается:

DateTime dateTime = new DateTime();
bool isFalse = dateTime == null;
bool isTrue  = dateTime != null;

Обратите внимание, что переменная dateTimeне nullable. Когда я наводю курсор на знак равенства, он говорит, что его подпись - bool DateTime.operator==(DateTime dateTime1, DateTime dateTime2), а null - Nullable<DateTime>.

Что здесь делает компилятор? Использует ли он какое-то неявное преобразование?

Я нашел похожий вопрос здесь , но он просто устраняет проблему и не объясняет, почему компилятор делает это.

1 Ответ

1 голос
/ 30 сентября 2019

В соответствии с правилами для Разрешение перегрузки бинарного оператора :

Операция вида x op y, где op - перегружаемый двоичный оператор, xявляется выражением типа X, а y является выражением типа Y, обрабатывается следующим образом:

  • Набор возможных пользовательских операторов, предоставляемых X иY для операции operator op(x,y) определяется. Набор состоит из объединения операторов-кандидатов, предоставляемых X, и операторов-кандидатов, предоставляемых Y, каждый из которых определяется с использованием правил пользовательских операторов-кандидатов. [...]

Кандидаты, определенные пользователем, говорит:

Для всех operator op объявлений в T0 и всех поднятых форм таких операторов , если по крайней мере один оператор применим к списку аргументов A, то набор операторов-кандидатов состоит из всех таких применимых операторов в T0.

Операторы отмены :

Операторы отмены разрешают предопределенные и определяемые пользователем операторы, которые работают наОбнуляемые типы значений, которые также должны использоваться с обнуляемыми формами этих типов. Поднятые операторы состоят из предопределенных и определенных пользователем операторов, которые удовлетворяют определенным требованиям, как описано ниже:

[...]

  • Для операторов равенства == != aподнятая форма оператора существует, если оба типа операндов являются необнуляемыми типами значений и если тип результата bool. Поднятая форма создается путем добавления одного модификатора ? к каждому типу операнда. Поднятый оператор считает два нулевых значения равными, а нулевое значение неравным любому ненулевому значению. Если оба операнда не равны NULL, оператор поднятого оператора разворачивает операнды и применяет базовый оператор для получения результата bool.

Таким образом, компилятор просматривает операнды DateTimenull, находит пользовательский ==(DateTime, DateTime) оператор и поднимает его до ==(DateTime?, DateTime?). Поскольку DateTime и null могут быть неявно преобразованы в DateTime?, этот отмененный оператор применим и в конечном итоге выбран в качестве лучшего кандидата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...