Is Nullable <int> a "Предопределенный тип значения" - или как работают Equals() и == здесь?
Для моей реализации метода Equals() я хочу проверить кучу внутренних полей. Я делаю это так:
...
_myNullableInt == obj._myNullableInt &&
_myString == obj._myString &&
...
Я бы предположил, что это сравнивает значения, включая null, для равенства, а не для адреса объекта (в качестве операции сравнения ссылочной эвтальности), поскольку:
Это сказано для "предопределенных типов значений" в этом документе MSDN здесь.
Я предполагаю, что Nullable<int>
является таким "предопределенным типом значений" из-за того, что он находится в пространстве имен System
в соответствии с этим документом MSDN.
Можно ли предположить, что здесь сравниваются значения VALUES?
Примечание. Ед. тесты показали "Да", но я хотел, чтобы другие были уверены в этом вопросе, на всякий случай, когда я что-то пропустил.
Ответы
Ответ 1
В С# существует концепция под названием "Поднятые операторы", описанная в разделе 7.3.7 спецификации языка (Версия 5 скачать):
Поднятые операторы допускают предопределенные и определяемые пользователем операторы, которые работают с типами значений, не допускающих нулевых значений, которые также могут использоваться с типами NULL для этих типов. Поднятые операторы построены из предопределенных и определяемых пользователем операторов, которые отвечают определенным требованиям, как описано ниже.
И конкретно:
Для операторов равенства
== !=
существует допустимая форма оператора, если типы операндов являются неинифицируемыми типами значений, и если тип результата равен bool. Поднятая форма строится путем добавления сингла? модификатора для каждого типа операнда. Поднятый оператор считает два нулевых значения равными, а нулевое значение не равно любому ненулевому значению. Если оба операнда не равны нулю, снятый оператор разворачивает операнды и применяет основной оператор для получения результата bool.
Итак, поскольку существует оператор ==
, определенный между int
s, также существует определенный для int?
s
Ответ 2
Если вы сравните эти значения, он на самом деле вызовет метод Nullable<T>.Equals
, поскольку оба значения имеют значение NULL с индексом.
Nullable<T>.Equals
в конечном итоге вызовет ключевое слово ==
compare для int, если оба значения не равны нулю. Поэтому, в конце концов, он действительно проверит значения.
Код из Equals
показывает это хорошо:
public override bool Equals(object other)
{
if (!this.HasValue)
{
return (other == null);
}
if (other == null)
{
return false;
}
return this.value.Equals(other);
}