简体   繁体   中英

C# is operator with nullable types always false according to ReSharper

I'm attempting to convert an object to a bool type and want to convert bool and Nullable<bool> types. I also want to make sure I make the appropriate casts where possible. So I have the following code:

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 informs me that value is bool? will always evaluate to false in this stack of if statements. Why is that? That would imply that Nullable<bool> doesn't inherit from object (impossible) or that value is bool will capture a bool? .

It's also possible that ReSharper 2016 has a bug; I see that the implementation of System.Windows.Controls.BooleanToVisibilityConverter.Convert is pretty much identical. I doubt that WPF core would have such a mistake in it, leading me to believe it's an issue with ReSharper.

When a value type is stored as object it is boxed . Boxing of Nullable<T> gets special treatment :

Objects based on nullable types are only boxed if the object is non-null. If HasValue is false, the object reference is assigned to null instead of boxing ... Boxing a non-null nullable value type boxes the value type itself , not the System.Nullable that wraps the value type.

And, per the documentation for is :

An is expression evaluates to true if the provided expression is non-null , and the provided object can be cast to the provided type without causing an exception to be thrown.

So, using both of these you can deduce (see fiddle ) that in the null case:

bool? x = null;
object obj = x;   // assigns obj = null
obj is bool?      // false, obj is null
obj is bool       // false, obj is null

And in the non-null case:

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

So ReSharper is correct: your first branch will evaluate as true if value is true or false (whether the object was assigned from a bool or bool? is not relevant or even known). The second branch will always be false in this case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM