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

时间:2016-01-29 10:24:50

标签: c# .net nullable c#-6.0 null-conditional-operator

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

的操作
DateTime? dt = DateTime.Now;
string x;
if(dt != null)
    x = dt.ToString("dd/MM/yyyy");

将抛出

  

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

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

x = dt?.ToString("dd/MM/yyyy");

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

3 个答案:

答案 0 :(得分:20)

因为Nullable<T>在C#中实现的方式使得该结构的实例显示为可空类型。如果您DateTime? Nullable<DateTime>实际为null,则当您将HasValue分配给false时,您需要在幕后设置nullHasValue ?.,您正在检查null等。<iframe width="560" height="315" src="https://www.youtube.com/embed/9T7eSyo7DRU" frameborder="0" allowfullscreen></iframe> 运算符的实现方式是它替换了对于可为空的结构也适用于引用类型的完全相同的习语。就像语言的其余部分一样,可以使用与可引用类型相似的可引用结构(关于img, iframe { max-width: 100%; } - ness)。

答案 1 :(得分:14)

简答:

DateTime?只是Nullable<DateTime>的甜蜜语法,它不包含DateTime的属性和方法,而 Elvis运算符适用于非可空Nullable<DateTime>.Value

<强> 说明:

以下代码:

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

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

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

旁注:string似乎在if内声明是无关紧要的,因为在MSIL级别提升,因为以后没有使用该值反编译器将其显示为在if范围内声明它。

如您所见,由于DateTime?只是Nullable<DateTime>的甜蜜语法,C#具有 Elvis运算符<{1}}的特定参考/ em>,使其返回值 不可为空的T本身

整个Nullable<T>的结果必须为Elvis operator 因此,如果您希望收到非Nullable值它必须是stringNullable<T>,但这并不会改变这样一个事实:如果运营商设法获得ReferenceType值本身 - 返回Nullable<DateTime>不再是DateTime

答案 2 :(得分:2)

考虑到:

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

此处dtDateTime?Nullable<DateTime>女巫不是IFormatable且没有ToString(string format)方法。

所以它扔了。

现在考虑:

x = dt?.ToString("dd/MM/yyyy");

?.是一个语法糖:

dt.HasValue ? dt.Value.ToString("dd/MM/yyyy"): null

此处dt.Value DateTimeIFormatableToString(string format)并且DateTime? dt = DateTime.Now; string x; if(dt.HasValue) x = dt.Value.ToString("dd/MM/yyyy"); 方法。

最后,在C#5.0中编写第一个代码的好方法是:

const initialState = {
    accessToken: null,
    isLoggedIn: false,
}