是吗??.除了检查null之外,运算符还做了什么?

iul*_*net 29 .net c# nullable c#-6.0 null-conditional-operator

您可能知道,DateTime?没有参数化ToString(为了格式化输出),并执行类似的操作

DateTime? dt = DateTime.Now;
string x;
if(dt != null)
    x = dt.ToString("dd/MM/yyyy");
Run Code Online (Sandbox Code Playgroud)

会扔

方法'ToString'没有重载需要1个参数

但是,由于C#6.0和Elvis(?.)运算符,上面的代码可以替换为

x = dt?.ToString("dd/MM/yyyy");
Run Code Online (Sandbox Code Playgroud)

哪....有效!为什么?

Joe*_*oey 20

因为Nullable<T>在C#中实现的方式使得该结构的实例显示为可空类型.当你DateTime?实际拥有它Nullable<DateTime>时,当你指定null它时,你将设置HasValuefalse幕后,当你检查null,你正在检查HasValue等等.?.操作符的实现方式是它取代了同样的习语.也适用于可为空的结构的引用类型.就像语言的其余部分一样,可以为nullable的结构类似于引用类型(关于null-ness).


Tam*_*red 14

简短回答:

DateTime?Elvis运算符在not-Nullable上运行时,Nullable<DateTime>它只是一个不包含DateTime属性和方法的甜蜜语法.Nullable<DateTime>.Value


说明:

以下代码:

DateTime? dt = DateTime.Now;
string x;
if (dt != null)
    x = dt?.ToString("dd/MM/yyyy");
Run Code Online (Sandbox Code Playgroud)

反编译时C# 5.0产生以下结果:

DateTime? nullable = new DateTime?(DateTime.Now);
if (nullable.HasValue)
{
    string str = nullable.HasValue ? nullable.GetValueOrDefault().ToString("dd/MM/yyyy") : null;
}
Run Code Online (Sandbox Code Playgroud)

旁注:string似乎在内部声明的内容if是无关紧要的,因为在该MSIL级别上提升,并且因为稍后在反编译器上使用的值显示它就好像它是在该if范围内声明的那样.

正如您所看到的,并且因为DateTime?它只是一个甜蜜的语法Nullable<DateTime>,C#对于Nullable<T>具有Elvis运算符的 s具有特定的引用,使其返回值成为不可为空的T本身.

因此,整体的结果Elvis operator必须是Nullable,如果你想要接收非string值,它必须是Nullable<T>或者a或者ReferenceType这不会改变这样一个事实:如果运算符设法获得Nullable<DateTime>值本身 - 返回DateTime的不是Nullable<DateTime>了.

  • 请选民下来,以便我可以改进我的答案. (4认同)
  • 哈哈,现在在`Visual Studio`上用`Release`编译它,它确实给出了同样的双重检查,我猜想缺少优化... (4认同)