Это потому, что компилятор автоматически генерирует так называемые поднятые операторы, которые также работают с обнуляемыми типами значений, которые вы можете прочитать в документах .Таким образом, для данного оператора сравнения T, U -> bool
, где T
и U
являются необнуляемыми типами значений, существуют также поднятые операторы T?, U -> bool
, T, U? -> bool
и T?, U? -> bool
.
Чтобы подавить эти операторы, вы можете явно определить их и украсить атрибутом Obsolete
с параметром error
, установленным в true
, следующим образом:
struct Value
{
public static bool operator ==(Value l, Value r)
{
return true;
}
public static bool operator !=(Value l, Value r)
{
return true;
}
[Obsolete("Some error message", error: true)]
public static bool operator ==(Value? l, Value r) =>
throw new NotImplementedException();
[Obsolete("Some error message", error: true)]
public static bool operator ==(Value l, Value? r) =>
throw new NotImplementedException();
[Obsolete("Some error message", error: true)]
public static bool operator ==(Value? l, Value? r) =>
throw new NotImplementedException();
[Obsolete("Some error message", error: true)]
public static bool operator !=(Value? l, Value r) =>
throw new NotImplementedException();
[Obsolete("Some error message", error: true)]
public static bool operator !=(Value l, Value? r) =>
throw new NotImplementedException();
[Obsolete("Some error message", error: true)]
public static bool operator !=(Value? l, Value? r) =>
throw new NotImplementedException();
}
Теперь в сравнениях типа new Value() == null
, а также new Value() == (Value?)null
будет выбран вышеуказанный соответствующий пользовательский оператор, так как он более конкретен и будет выдана такая ошибка:
ошибка CS0619: 'Value.operator == (Value, Value?) 'устарел: «Некоторое сообщение об ошибке»