С MSDN :
Поднятые операторы разрешают предопределенные и определяемые пользователем операторы, которые работают с ненулевыми типами значенийтакже для использования с обнуляемыми формами этих типов. Поднятые операторы состоят из предопределенных и определяемых пользователем операторов, которые отвечают определенным требованиям, как описано ниже:
...
Для операторов равенства
== !=
существует поднятая форма оператора, если оба типа операндов являются необнуляемыми типами значений и если тип результата равен bool
. Поднятая форма создается путем добавления одного модификатора ?
к каждому типу операнда. Поднятый оператор считает два нулевых значения равными, а нулевое значение неравным любому ненулевому значению. Если оба операнда не равны NULL, оператор поднятого оператора разворачивает операнды и применяет базовый оператор для получения результата bool
.
Вы не используете оператор:
bool ==(ulong left, ulong right)
Вы используете поднятый оператор:
bool ==(ulong? left, ulong? right)
Этот оператор принимает два ulong?
параметра и возвращает true, если оба имеют значение NULL или оба имеют ненулевое значение и имеют одинаковое значение.
Вы, вероятно, смотрите на Visual Studio, которая действительно показывает вам что-то запутанное в этом случае:
Донне путайтесь с этим - как @mjwills указал в комментариях, это известная проблема .
Если вы напишите это:
public bool M(ulong a, ulong? b) {
return a == b;
}
Затем компилятор выдает следующий код:
public bool M(ulong a, ulong? b)
{
ulong? num = b;
return (a == num.GetValueOrDefault()) & num.HasValue;
}
num.GetValueOrDefault()
возвращает 0
, если b
равно null
, в противном случае значение b
. Таким образом, M
возвращает true
тогда и только тогда, когда b
не равно нулю и имеет то же значение, что и a
.
SharpLab