C# 安全导航运算符 - 实际发生了什么?

标签 c# c#-6.0 null-conditional-operator

我一直对 C#6 中添加的安全导航运算符功能感兴趣。我已经期待了一段时间了。但我发现了一些与我预期不同的行为。我意识到我真的不明白它是如何工作的。

给定这个类

class Foo {
    public int? Measure;
}

下面是一些使用 new 运算符的代码。

Foo f = new Foo { Measure = 3 };
Console.WriteLine(f?.Measure);  // 3

f = new Foo { Measure = null };
Console.WriteLine(f?.Measure);  // null

f = null;
Console.WriteLine(f?.Measure);  // null

到目前为止,一切都按预期进行。 ?. 当左边不为空时访问成员,否则返回空。但事情朝着我意想不到的方向发展。

var i = f?.Measure; // i is Nullable<int>
Console.WriteLine(i.HasValue); // false
Console.WriteLine(f?.Measure.HasValue); // null

什么?

为什么我可以从 i 获得 HasValue,但不能从分配给 i 的相同表达式获得? HasValue 怎么可能为空?

编辑:我真正的问题是关于程序行为,而不是编译错误。我删除了关于编译的额外内容,并将这个问题更狭隘地集中在为什么看似相同的逻辑会返回两个不同的结果。

最佳答案

让我们从逻辑上分析一下。

var f = ???;
var i = f?.Measure;
var t = i.HasValue;

我们不知道 f是否为空。

  1. 如果f null,则结果(i)是null
  2. 如果f 不是 null,则结果 ( i ) 是一个 int

因此,i定义为 int? , 和 tbool

现在,让我们来看看这个:

var f = ???;
var i = f?.Measure.HasValue;
  1. 如果f null,则结果(i)是null
  2. 如果f 为null,则结果(i)为Measure.HasValue ,这是一个 bool 值。

因此,ibool? .

如果f为空,我们短路并返回空。如果不是,我们返回 bool .HasValue 的结果.

本质上,当使用 ?. 时- 返回类型必须是一个引用值,或者一个Nullable<T> ,因为表达式可以短路以返回 null。

关于C# 安全导航运算符 - 实际发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32261869/

相关文章:

c# - 评估方法 System.Linq.Enumerable.ToList() 调用 QuickWatch 中的本地方法 Interop+Kernel32.FindStringOrdinal()

c# - if 语句中的空条件 boolean 值

c# - Resharper 重新设计了一个 for 循环。这个 LINQ 语句在一行中做的事情太多了吗?

c# - 这怎么可能不是一个常数值呢?

c# - 在 C# 中,我应该使用 Enum、static Class、Dictionary 还是 Struct 来表示这些 "labeled floats"?

C# 将控制台应用程序挂接到记事本

c# - 使用 nameof 获取当前方法的名称

msbuild - 在 C# 6.0 代码库的 psake 构建中强制使用 MSBuild 14.0

c# - Null 条件运算符和 void 方法

c# - 如何将 Nullable 运算符与 Null 条件运算符一起使用?