我想知道是否有人有一个文档源或一个很好的解释,一个布尔结果操作和空条件访问操作符之间的交互的确切规则/实现。我一直在使用它们,它们通常会做我想让它们做的事情,但有时它们会以一种我似乎无法完全理解的“有趣”的方式行事。当我分解代码时,它既有意义又没有意义。下面是一个例子:
string str = null;
if (str?.Length != 0) //evaluates to true - str is null, therefore Length is null(able?) and is a value other than zero
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
if (str?.Length > 0) //evaluates to false - str is null, therefore Length is null(able?) and null is not greater than zero
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
然而,与第一个示例等价的逻辑计算结果为false,正如我所期望的那样:
string str = null;
//However, the 'equivalent' logic evaluates to false.
if (str != null && str.Length != 0)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
那么,在引擎盖下,到底发生了什么,为本质上逻辑等价的代码创建了不同的行为?我希望str的短路?.返回false,因为后面的所有内容都是布尔值。由于与空引用相关联而“无效”,但情况并非如此。或者代码示例不在逻辑上是等价的,因为我缺少/不理解某些东西?
我想.Net正在做一些事情,将'0'和'Length'转换为可空的int,并在它们之间进行一些相互作用,但实际上我不能使用可空的int重新创建代码,以重现
if (str?.Length != 0)
{
Console.WriteLine("True");
}
else
{
Console.WriteLine("False");
}
有人能告诉我发生了什么吗?我不得不压制一些愚蠢的错误有关的误用'?我希望以后能避免这种事
我已经看过https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators,它似乎没有解决我的问题的细节。
2条答案
按热度按时间goqiplq21#
你应该看过可空值类型(C#参考),在提升运算符下,你会看到下面的段落:
对于比较运算符〈、〉、〈=和〉=,如果一个或两个操作数都为null,则结果为false;否则,比较所包含的操作数的值。不要假设因为一个特定的比较(例如,〈=)返回false,相反的比较(〉)返回true。
ulmd4ohb2#
你不是这么写的。
Null-conditional
运算符**不是在运算结果为null时返回false
**的快捷方式。它只是防止您在object为null时访问property。如果您将
str?.Length
提取到变量中,如下所示:var count = str?.Length;
你会看到count
是null。所以你要做的是:
结果为
true
。如果你不想得到预期的结果,你也应该使用null-coalescing
运算符,像这样:如果你不想知道编译器生成了什么,请查看this网站。例如:
str?.Length != 0;
编译为text == null || text.Length != 0;
,而str?.Length > 0
编译为text != null && text.Length > 0