Рассмотрим следующий код:
DateTime t = DateTime.Today;
bool isGreater = t > null;
С Visual Studio 2010 (С# 4,.NET 4.0) я получаю следующее предупреждение:
warning CS0458: Результат выражения всегда "null" типа "bool?"
Это неверно; результат всегда false
(типа bool
):
Теперь структура DateTime перегружает оператор >
(больше). Любая недействительная структура (например, DateTime) неявно конвертируется в соответствующий тип Nullable<>
. Вышеприведенное выражение в точности эквивалентно
bool isGreater = (DateTime?)t > (DateTime?)null;
который также генерирует одно и то же неправильное предупреждение. Здесь оператор >
- оператор снят. Это работает, возвращая false, если HasValue
любого из двух операндов false
. В противном случае оператор, поднятый, перейдет к разворачиванию двух операндов к базовой структуре, а затем вызовет перегрузку >
, определенную этой структурой (но это не обязательно в этом случае, когда один операнд не имеет значения HasValue
).
Можете ли вы воспроизвести эту ошибку, и эта ошибка известна? Я что-то не понял?
Это то же самое для всех типов структур (не простых типов типа int
, а не типов перечислений), которые перегружают соответствующий оператор.
(Теперь, если мы используем ==
вместо >
, все должно быть полностью схожим (потому что DateTime также перегружает оператор ==
), но это не похоже. Если я скажу
DateTime t = DateTime.Today;
bool isEqual = t == null;
Я получаю предупреждение no ☹ Иногда вы видите, что люди случайно проверяют переменную или параметр для null, не понимая, что тип их переменной является структурой (которая перегружает ==
и которая не является простой тип типа int
). Было бы лучше, если бы они получили предупреждение.)
Обновление: С помощью компилятора С# 6.0 (на основе Roslyn) Visual Studio 2015 неверное сообщение с isGreater
выше изменяется на CS0464 с правильным и полезным предупреждающим сообщением. Кроме того, отсутствие предупреждения с isEqual
выше фиксировано в VS2015 компиляторе, но только если вы скомпилируете с /features:strict
.