如果条件不工作,则短路

本文关键字:短路 工作 条件 如果 | 更新日期: 2023-09-27 18:12:46

我有一个抛出NullReferenceException的代码段。代码段如下:

if (string.IsNullOrWhiteSpace(user.FirstName) && !(user.FirstName.Length <= 64))
{
    // Some Code
}

这里if条件首先应该检查user.FirstName是否为Null或WhiteSpace。当user.FirstName的值为null时,此代码段抛出NullReferenceException。我假设这是通过检查user.FirstNameLength抛出的,但由于这是一个短路检查,不应该第一个表达式满足条件并执行if块内的代码。

如果条件不工作,则短路

第二部分只在

string.IsNullOrWhiteSpace(user.FirstName)

的结果为true。所以你需要

!string.IsNullOrWhiteSpace(user.FirstName) && !(user.FirstName.Length <= 64)

string.IsNullOrWhiteSpace(user.FirstName) || !(user.FirstName.Length <= 64)

根据您的要求。此外,user也可能是null,在这种情况下,短路根本不起作用。

在发布工作断言之前,让我们分析一下您的问题c#解决方案包含十亿行代码:你真的这么认为吗像if这样的普通结构可以不工作吗?)

似乎你想检查用户名是否无效一:

  1. 如果用户名为空或空或空白
  2. 或者如果太长(超过64个字符)

现在实现很清楚了:

  const int USER_NAME_MAX_LENGTH = 64;
  if (string.IsNullOrWhiteSpace(user.FirstName) || 
      user.FirstName.Length > USER_NAME_MAX_LENGTH) {
    // user name is invalid
    ...   
  }

在您的示例中,您可以有两个不同的NullReferenceException原因:

- Value `user` is null;
- `user.FirstName` is null.

我假设你已经检查了如果user不是null,所以让我们跳过那一个。

现在让我们假设user.FirstName是空的,然后会发生什么?

第一个条件string.IsNullOrWhiteSpace(user.FirstName)将导致true。这是否足以让if语句执行内部代码块,或者还应该评估第二个条件?

让我们看一下这个真值表:

A  && B     = RESULT
--------------------
False False = False
False True  = False
True  False = False
True  True  = True

因此,当使用&& -运算符时,只有当两个子条件都为真时,总条件才为真。所以当第一个条件为真时,第二个条件仍然需要求值。根据c#对真值表的简单翻译是(where ???)代表:Don't care):

A  && B     = RESULT
--------------------
False ???   = False
True  False = False
True  True  = True

所以当检查第二个条件时,读取属性user.FirstName.Length,得到NullReferenceException

如何预防。正如其他人所说,您可能希望在以下情况下执行代码块:FirstName是NULL Empty WhiteSpace 大于64。你当前的条件检查,基本上,如果FirstName是NULL 大于64。

所以…使用:

if (string.IsNullOrWhiteSpace(user.FirstName) || !(user.FirstName.Length <= 64))

或更清楚:

if (string.IsNullOrWhiteSpace(user.FirstName) || (user.FirstName.Length > 64))
c#的真值表应该是:
A  || B     = RESULT
--------------------
False False = False
False True  = True
True  ???   = True

你可以清楚地看到"short circuit"部分

&&不会像你期望的那样短路,它恰恰相反。

如果第一个条件为真,它需要检查两个条件,只有当两个条件都为真时,它才会执行里面的块:如果第一个条件为真(即user.FirstName为空),那么它需要检查第二个条件是否也为真,因此你的异常(因为user.FirstName总是为空-除非它是空的或空白-当检查它的Length时)。

编辑:由于上述段落对某些人来说似乎不清楚:我不是说&&不会短路(如果第一个条件是false,它会短路),我是说它不会像OP

预期的那样短路