空安全解引用运算符一达到空值就停止对整个表达式的求值。所以如果deserializedBody
为空,它不会尝试评估date
,也不会调用ToString()
任何东西——所以你不会得到异常。
完整示例:
using System;
class Test
{
DateTime date = DateTime.UtcNow;
static void Main()
{
Test t = null;
// No exception thrown
Console.WriteLine(t?.date.ToString());
}
}
这里的表达式t?.date.ToString()
等价于:
t is null ? null : t.date.ToString()
(除了t
只评估一次)。它不等于
(t is null ? null : t.date).ToString()
...这就是我怀疑你期望它做的事情。
但是不,这并不能防止deserializedBody
非空但deserializedBody.date
为空的情况。
如果您因 C# 8 可空引用类型而期待警告,我相信动态表达式永远不会进行空检查。作为一个例子,考虑:
class Test
{
public string? foo;
}
class Program
{
static void Main(string[] args)
{
Test t = new Test();
dynamic d = t;
Console.WriteLine(t.foo.Length); // Warning
Console.WriteLine(d.foo.Length); // No warning
Console.WriteLine(d.bar); // No warning for this either
}
}
我怀疑这样做的原因是编译器基本上没有关于什么d.foo
的信息。对于每一种有有用警告的情况,都会有另一种警告没有用的情况。当您处于动态键入领域时,您已经接受了一定程度的风险——d.foo
当访问d.foo
开始时警告取消引用是有风险的,这似乎很奇怪。