C# является оператором с обнуляемыми типами, всегда ложными согласно ReSharper
Я пытаюсь преобразовать object
к bool
введите и хотите конвертировать bool
а также Nullable<bool>
типы. Я также хочу убедиться, что я делаю соответствующие приведения, где это возможно. Итак, у меня есть следующий код:
if (value is bool)
{
boolValue = (bool) value;
}
else if (value is bool? && ((bool?)value).HasValue)
{
boolValue = ((bool?) value).Value;
}
else
{
throw new ArgumentException("Value must be a boolean type");
}
ReSharper 2016 сообщает мне, что value is bool?
всегда будет иметь значение false в этом стеке операторов if. Это почему? Это будет означать, что Nullable<bool>
не наследуется от object
(невозможно) или что value is bool
захватит bool?
,
Также возможно, что в ReSharper 2016 есть ошибка; Я вижу, что реализация System.Windows.Controls.BooleanToVisibilityConverter.Convert
в значительной степени идентична. Я сомневаюсь, что в ядре WPF возникла бы такая ошибка, что заставило меня поверить, что это проблема с ReSharper.
1 ответ
Когда тип значения хранится как object
это в штучной упаковке. Бокс Nullable<T>
получает специальное лечение:
Объекты, основанные на обнуляемых типах, помещаются в квадрат, только если объект ненулевой. Если значение HasValue равно false, ссылка на объект присваивается пустому, а не упаковывается в боксы... В боксе с ненулевым типом значения, содержащим значения NULL, помещается сам тип значения, а не System.Nullable, который переносит тип значения.
И, согласно документации дляis
:
Выражение is оценивается как true, если предоставленное выражение не является нулевым, и предоставленный объект может быть приведен к предоставленному типу, не вызывая исключение.
Итак, используя оба из них, вы можете сделать вывод (см. Fiddle), что в нулевом случае:
bool? x = null;
object obj = x; // assigns obj = null
obj is bool? // false, obj is null
obj is bool // false, obj is null
И в ненулевом случае:
bool? x = true;
object obj = x; // obj is boxed bool (true)
obj is bool? // true, obj unboxes to bool?
obj is bool // true, obj unboxes to bool
Так что ReSharper верен: ваша первая ветка будет оцениваться как true
если value
является true
или же false
(был ли объект назначен из bool
или же bool?
не актуально или даже не известно). Вторая ветка всегда будет false
в этом случае.