如果条件不工作,则短路
本文关键字:短路 工作 条件 如果 | 更新日期: 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.FirstName
的Length
抛出的,但由于这是一个短路检查,不应该第一个表达式满足条件并执行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
这样的普通结构可以不工作吗?)
似乎你想检查用户名是否无效一:
- 如果用户名为空或空或空白
- 或者如果太长(超过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