“.” 运算符除了检查 null 之外是否还执行任何其他操作
本文关键字:是否 执行 任何 操作 其他 运算符 null 检查 | 更新日期: 2023-09-27 18:32:28
您可能知道,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");
哪。。。。工程!为什么?
因为Nullable<T>
是在 C# 中实现的,使该结构的实例显示为可为 null 的类型。当你有DateTime?
它实际上是Nullable<DateTime>
,当你分配null
时,你正在设置HasValue
在幕后false
,当你检查null
时,你正在检查HasValue
,等等。?.
运算符的实现方式只是替换了适用于引用类型(也适用于可为空结构(的相同习惯用法。就像语言的其余部分一样,使可空结构类似于引用类型(关于null
-ness(。
简短回答:
DateTime?
只是Nullable<DateTime>
的甜蜜语法,它不包含DateTime
的属性和方法,而猫王运算符在不可为空的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 运算符的 Nullable<T>
s 有一个特定的引用,使其返回值本身为不可为空的 T。
整个Elvis operator
的结果必须Nullable
因此,如果要接收非string
值,则必须是Nullable<T>
值或ReferenceType
,但这不会改变这样一个事实,即如果运算符设法获取了Nullable<DateTime>
值本身 - 返回的DateTime
不再Nullable<DateTime>
。
考虑:
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)
方法。
最后,在 C# 5.0 中编写第一个代码的好方法是:
DateTime? dt = DateTime.Now;
string x;
if(dt.HasValue)
x = dt.Value.ToString("dd/MM/yyyy");