根据ReSharper,带有可空类型的C# is运算符始终为false。

7

我正在尝试将一个object转换为bool类型,并且想要转换boolNullable<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告诉我,在这一堆if语句中,value is bool?将永远评估为false。为什么呢?这意味着Nullable<bool>没有继承自object(不可能),或者value is bool会捕获一个bool?
ReSharper 2016也有可能存在错误;我发现System.Windows.Controls.BooleanToVisibilityConverter.Convert的实现几乎完全相同。我怀疑WPF核心不会有这样的错误,这让我认为这是ReSharper的问题。
1个回答

10

当值类型被存储为 object 时,它会被 装箱。对于 Nullable<T> 的装箱则会得到特殊处理

基于可空类型的对象仅在对象为非 null 时才被装箱。如果 HasValue 为 false,则将对象引用赋值为 null 而不是装箱... 对非 null 的可空值类型装箱的是值类型本身,而非包装值类型的 System.Nullable。

此外,根据is 的文档

如果提供的表达式非 null,并且提供的对象可以转换为提供的类型,而不会引发异常,则 is 表达式的求值结果为 true。

因此,结合这两个知识点,您可以推断出(请参见示例),在 null 情况下:

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是正确的:如果value为true或false(无论该对象是否分配自bool或bool?),则第一个分支将评估为true。在这种情况下,第二个分支始终为false。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接