.Net 7 -空条件访问运算符(?). or?[])布尔求值中的规则

yquaqz18  于 2023-05-02  发布在  .NET
关注(0)|答案(2)|浏览(149)

我想知道是否有人有一个文档源或一个很好的解释,一个布尔结果操作和空条件访问操作符之间的交互的确切规则/实现。我一直在使用它们,它们通常会做我想让它们做的事情,但有时它们会以一种我似乎无法完全理解的“有趣”的方式行事。当我分解代码时,它既有意义又没有意义。下面是一个例子:

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,它似乎没有解决我的问题的细节。

goqiplq2

goqiplq21#

你应该看过可空值类型(C#参考),在提升运算符下,你会看到下面的段落:
对于比较运算符〈、〉、〈=和〉=,如果一个或两个操作数都为null,则结果为false;否则,比较所包含的操作数的值。不要假设因为一个特定的比较(例如,〈=)返回false,相反的比较(〉)返回true。

ulmd4ohb

ulmd4ohb2#

你不是这么写的。Null-conditional运算符**不是在运算结果为null时返回false**的快捷方式。它只是防止您在object为null时访问property。
如果您将str?.Length提取到变量中,如下所示:var count = str?.Length;你会看到count是null。
所以你要做的是:

if (null != 0)
{
    Console.WriteLine("True");
}
else
{
    Console.WriteLine("False");
}

结果为true。如果你不想得到预期的结果,你也应该使用null-coalescing运算符,像这样:

int valueIfNull = -1;

if ((str?.Length ?? valueIfNull) != 0)
{
    Console.WriteLine("True");
}
else
{
    Console.WriteLine("False");
}

如果你不想知道编译器生成了什么,请查看this网站。例如:str?.Length != 0;编译为text == null || text.Length != 0;,而str?.Length > 0编译为text != null && text.Length > 0

相关问题