使用可空bool的条件表达式会产生编译器错误

时间:2014-11-13 05:03:37

标签: c#

请参阅以下属性:

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

我对此属性的目标是执行以下操作:

  • 如果LeftChecked和RightChecked都等于false
  • ,则返回null
  • 如果LeftChecked等于true,则返回“L”
  • 否则返回“R”

这可以按照我的预期运作,但现在我想做类似的事情,除了一个布尔?而不是一个字符串。请参阅以下属性。

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

然而,这给了我以下错误:

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

所以我用if-else改写了它......

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

我使用if-else方法没有问题,但我真的很好奇为什么我的原始属性不起作用,即使它几乎与有效的字符串属性相同。

我已经阅读了一些诸如此类Compiler Error for Nullable Bool之类的问题但是我没有遇到过类似情况。

3 个答案:

答案 0 :(得分:3)

这应该有效:

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

答案 1 :(得分:1)

我不明白使用PassChecked ? true : false这个词。 PassChecked属性已为bool类型。通过三元运算符发送它只是为了返回与原始值相同的新bool值是什么意思?

这(与评论中的slugster的建议几乎相同)应该同样有效:

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

或者,如果您更喜欢原始表达式的基本结构:

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

我更喜欢(bool?)nulldefault(bool?),但这完全是品味问题。它们是等同的,并且同样有效。

答案 2 :(得分:0)

原始问题中的代码现在使用 target typed conditional expression 功能在 C# 9 中“可以正常工作”。


历史上,条件运算符的类型是通过查看后两个操作数的类型来确定的,如果存在从一个操作数到另一个操作数的转换,那么我们使用“另一个”操作数作为运算符的类型。 (simplifying a bit。)

在这种情况下,我们有一个操作数是 null,另一个操作数是 bool 类型。在这种情况下,只有 bool 操作数具有类型,而 null 不能转换为 bool,因此 C# 9 之前的语言无法确定类型条件表达式。

现在我们有了目标类型的条件表达式,编译器可以观察到这个表达式用在需要 bool? 类型的值的位置。基于此,它只是尝试将每个操作数转换为 bool?。表达式 null 可以很好地转换为 bool?,类型 bool 也是如此,因此它在这种情况下做正确的事情并为条件运算符提供类型 bool?