【问题标题】:AND operation cannot be applied between nullable bools不能在可为空的布尔值之间应用 AND 操作
【发布时间】:2011-05-19 22:33:09
【问题描述】:

我在两个可为空的布尔值 (bool?) 之间应用 AND 运算 (&&),但它给了我错误

运算符&& 不能应用于bool?bool? 类型的操作数

如何在包含两个可为空的布尔值的语句中应用和操作?

如果我有一个像

这样的对话结果
dialog.ShowDialog () == DialogResult.OK

如何将其转换为可空布尔值,因为我需要将'&&' 运算符与它放在另一个操作数返回可空布尔值的 if 条件中? 这是代码:

if (dialog.ShowDialog () == DialogResult.OK && CheckProjectPath(dialog.FileName, true))

此 if 条件中的第二个操作数是可为空的布尔值。

【问题讨论】:

  • 左侧操作数不能为空,第二个操作数返回可为空的布尔型。现在我得到的编译错误 isOperator '&&' 不能应用于 'bool' 和 'bool' 类型的操作数?
  • CheckProjectPath 方法的结果是 Nullable bool 吗?
  • true && null 需要什么行为?
  • 第二个操作数是可以为空的布尔型,不一定为空。我有是,否,取消的消息框。因此我需要三个布尔值。

标签: c# operators nullable


【解决方案1】:

如何在包含两个可为空的布尔值的语句中应用和操作?

好吧,你想发生什么?这是非法的原因是因为如果第一个操作数为空,就会发生不好的事情。

x && y 对可空的布尔值 x 和 y 意味着什么?那么,一个可为空的布尔值首先意味着什么?可为空的布尔值表示以下三种情况之一:

  • 条件绝对正确
  • 条件肯定是假的
  • 条件是真还是假,但我们不知道是哪一个

那么x && y 是什么意思?它的意思是“仅当条件 x 为真时才评估 y”,但如果 x 可以为空,那么 我们可能不知道 x 表示的条件是否为真

例如,假设我们有:

gotMoneyInZurich = SalesForNovemberWereMoreThanAMillionBucks() &&
    TryToDepositAMillionBucksInASwissBankAccount();

如果 SalesForNovemberWereMoreThanAMillionBucks 为假,则不要尝试存入钱,我们知道银行里没有钱。如果是真的,那就试着存钱;如果失败了,那么我们在苏黎世就没有钱了;如果成功了,我们就会这样做。

现在假设并不是所有的销售人员都报告了他们 11 月份的销售数据。我们知道 11 月的销售额是否超过一百万美元吗?不,十一月已经过去;销售额要么是,要么不超过一百万美元,但现在我们不知道。正确答案不是“假”,正确答案不是“真”:正确答案是“我们不知道”:null。

那么如果第一个操作数返回null,该怎么办呢?我们不知道销售额是否超过一百万美元,那么尝试存钱或不存钱是正确的做法吗?您是否应该根据丢失的信息采取行动?

编译器没有能力为你决定这个问题。如果你想在结果未知的情况下不存钱,那么你必须说:(SalesForNovemberWereMoreThanAMillionBucks() ?? false)表示“如果结果为空,将其视为假”。

同样,如果你说:

if(x && y)
    Frob();

x 为真,y 为空,那该怎么办呢?您是在说“只有当 x 和 y 都为真时才Frob。x 为真,我们不知道 y 是否为真”。那么你应该Frob吗? 你不知道编译器也不知道。如果你想说的是“Frob if x is true and y is either true or null”,那么说:

if(x && (y ?? true))
    Frob();

或者,“如果 x 为真且 y 为真,则 frob,但如果 y 为空,则不会”然后说:

if(x && (y ?? false))
    Frob();

现在,如果您不使用&& 运算符进行短路评估,那么首先不要使用&& 运算符。使用& 运算符;它总是评估双方,所以这里没有歧义。如果xy 是可以为空的布尔值,那么说x & y 是完全合法的。当然,你仍然不能在if 中使用那个东西;这需要一个布尔值,而不是一个可为空的布尔值。但你可以说: 布尔?结果 = x & y; 其中xy 是可为空的布尔值。

【讨论】:

  • "如果 x 或 y 为空,则结果为空,如果 x 和 y 都为真,则结果为真,否则为假" 不正确;见here。 A 我认为更好的方法是说a&bfalse,如果其中一个是false(一个false 值伪造和),true 如果两者都是true,否则null。同样,a|btrue,如果其中一个是 true(一个 true 满足或),false 如果两者都是 false,或者 null,否则。
  • @Adam:我在编译器中实现了这些规则;你会认为我能够正确地描述它们。 :) 感谢您的注意。
  • 谢谢 :) 当我看到你是我四倍检查的答案的作者时,我会承认。
【解决方案2】:

你可以使用类似的东西

bool? b1 = ...;
bool? b2 = ...;    
bool b = (b1 ?? true) && (b2 ?? false);

您必须选择自己的默认值。

如何将其转换为可空布尔值,因为我需要将 '&&' 运算符与它放在另一个操作数返回可空布尔值的 if 条件中?

你应该走另一条路:你不能对一个可以为空的操作数进行操作,所以你必须尝试从bool?转换为bool。运营商 ??在这里非常有用:

 if (dialog.ShowDialog () == DialogResult.OK 
     && CheckProjectPath(dialog.FileName, true) ?? false)

关于"null-coalescing operator" ?? :

int? a, b, c;
...
int d = a ?? b ?? c ?? -1;

如果 a、b 和 c 都是 null,则 d 变为 -1。如果其中任何一个不为空,则使用第一个值。

【讨论】:

  • 我不明白“??”的用法这里的操作数。如果它不为空,它将返回左侧操作数;否则返回正确的操作数。
【解决方案3】:
if (dialog.ShowDialog () == DialogResult.OK &&
    CheckProjectPath(dialog.FileName, true).GetValueOrDefault())

&& 操作没有为nulls 定义。因此,您必须确保两个布尔值都不可为空,最简单的方法是调用可空布尔值的GetValueOrDefault() 方法。

【讨论】:

    【解决方案4】:
    if (dialog.ShowDialog () == DialogResult.OK) 
    {
        var checkProjectPath =  CheckProjectPath(dialog.FileName, true);
        if (checkProjectPath.HasValue && checkProjectPath)) {/*Your Action*/}
    }
    

    如果 CheckProjectPath 函数的目的是验证路径,我看不出结果应该是 bool? 的任何原因

    【讨论】:

      【解决方案5】:

      我猜你可以试试

      if ((dialog.ShowDialog() == DialogResult.OK )&& 
                  (CheckProjectPath(dialog.FileName, true) == true ) )
      

      【讨论】:

      • 是的,但很棘手。你不能用bool&& 但是当你使用== 时它总是错误的。请注意,以... == false)) 结尾会给出相同的答案。
      • 你的意思是万一 (CheckProjectPath(dialog.FileName, true) 为空?但是我们同时回答了,当我读到你的回答时,我知道我的回答是一种解决方法。我只是坚持== 运算符将返回一个 bool 而不是可为空的 bool..
      猜你喜欢
      • 1970-01-01
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      相关资源
      最近更新 更多