learningcs
learningcs

Reputation: 1926

Conditional expression with nullable bool produces compiler error

See the following property:

public bool LeftChecked {get;set;}
public bool RightChecked {get;set;}
public string LeftRight
{
    get
    {
        return !LeftChecked && !RightChecked ? null :
            LeftChecked ? "L" : "R";
    }
}

My goal with this property was to do the following:

This works as I expect it, but now I would like to do something similar, except with a bool? instead of a string. See the following property.

public bool PassChecked {get;set;}
public bool FailChecked {get;set;}
public bool? PassFail
{
    get
    {
        return !PassChecked && !FailChecked ? null :
            PassChecked ? true : false;
    }
}

However, this gives me the following error:

Type of conditional expression cannot be determined because there is no implicit conversion between '<null>' and 'bool'

So I rewrote it using if-else instead...

public bool? PassFail
{
    get
    {
        if (!PassChecked && !FailChecked) return null;
        else return PassChecked ? true : false;
    }
}

I have no problems with using the if-else method, however I'm really curious why my original property would not work, even though it is almost the same as the string property which worked.

I have read a few SO questions such as this Compiler Error for Nullable Bool however I have not come across any with similar circumstances.

Upvotes: 1

Views: 736

Answers (3)

Rikki Gibson
Rikki Gibson

Reputation: 4337

The code in the original question now "just works" in C# 9 using the target typed conditional expression feature.


Historically, the conditional operator's type was determined by looking at the type of the latter two operands, and if a conversion exists from one operand to the other operand, then we use the "other" operand as the operator's type. (simplifying a bit.)

In this case, we have one operand that is null, and another operand of type bool. Only the bool operand has a type in this case, and null can't be converted to bool, so the language pre-C# 9 wasn't able to determine a type for the conditional expression.

Now that we have target typed conditional expressions, the compiler can observe that this expression is used in a position where a value of type bool? is required. Based on this it simply tries converting each operand to bool?. The expression null converts to bool? just fine, as does the type bool, so it just does the right thing in this scenario and gives the conditional operator the type bool?.

Upvotes: 0

Peter Duniho
Peter Duniho

Reputation: 70652

I don't understand using the expression PassChecked ? true : false. The PassChecked property is already of type bool. What's the point of sending it through the ternary operator just to return new bool values identical to the original value?

This (practically the same as the suggestion by slugster in the comments) should work just as well:

return PassChecked ? true : FailChecked ? false : (bool?)null;

Alternatively, if you prefer the basic structure of the original expression:

return (!PassChecked && !FailChecked) ? (bool?)null : PassChecked;

I prefer (bool?)null to default(bool?), but it's strictly a matter of taste. They are equivalent and work equally well.

Upvotes: 2

kelsier
kelsier

Reputation: 4100

This should work :

return !PassChecked && !FailChecked ? null :
            PassChecked ? (bool?)true : (bool?)false;

Upvotes: 3

Related Questions