您可能知道,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");
哪个......有效!为什么呢?
答案 0 :(得分:20)
因为Nullable<T>
在C#中实现的方式使得该结构的实例显示为可空类型。如果您DateTime?
Nullable<DateTime>
实际为null
,则当您将HasValue
分配给false
时,您需要在幕后设置null
到HasValue
?.
,您正在检查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
值它必须是string
或Nullable<T>
,但这并不会改变这样一个事实:如果运营商设法获得ReferenceType
值本身 - 返回Nullable<DateTime>
不再是DateTime
。
答案 2 :(得分:2)
考虑到:
DateTime? dt = DateTime.Now;
string x;
if(dt != null)
x = dt.ToString("dd/MM/yyyy");
此处dt
是DateTime?
或Nullable<DateTime>
女巫不是IFormatable
且没有ToString(string format)
方法。
所以它扔了。
现在考虑:
x = dt?.ToString("dd/MM/yyyy");
?.
是一个语法糖:
dt.HasValue ? dt.Value.ToString("dd/MM/yyyy"): null
此处dt.Value
DateTime
是IFormatable
,ToString(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,
}