? (可为空)在C#中的运算符
通过在值types数据types上应用可为空的运算符来更改什么,现在它可以存储空值。
正如其他人所说,“?” 只是将其改为Nullable<T>
简写。 这只是另一个带有布尔标志的值types,用于表示是否有真正有用的值,或者是否为types的空值。 换句话说, Nullable<T>
看起来有点像这样:
public struct Nullable<T> { private readonly bool hasValue; public bool HasValue { get { return hasValue; } } private readonly T value; public T value { get { if (!hasValue) { throw new InvalidOperationException(); } return value; } } public Nullable(T value) { this.value = value; this.hasValue = true; } // Calling new Nullable<int>() or whatever will use the // implicit initialization which leaves value as default(T) // and hasValue as false. }
显然在实际的代码中有更多的方法(如GetValueOrDefault()
)和转换运算符等。C#编译器增加了提升的运算符,有效地代理T
的原始运算符。
听起来像一个破碎的logging的风险,这仍然是一个价值types。 它不涉及拳击…当你写:
int? x = null;
那不是一个空引用 – 它是Nullable<int>
的空值,也就是hasValue
为false
那个。
当一个可为空的types被装箱时,CLR有一个特性,它的值被装箱到一个空引用,或一个普通的盒装T.因此,如果你有这样的代码:
int? x = 5; int y = 5; object o1 = x; object o2 = y;
o1
和o2
所指的盒装值是无法区分的。 你不能说这是一个可空types的结果。
这个?
语法是对Nullable<T>
结构的语法糖。
从本质上讲,当你写int? myNullableInt
int? myNullableInt
,编译器将其更改为Nullable<int> myNullableInt
。
从MSDN (向下滚动到“可空types概述”):
语法T? 是Nullable的简写,其中T是一个值types。 这两种forms是可以互换的。
值types本身没有任何变化,它只是包装在System.Nullable<T>
结构中。 http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx
types从以前的版本改为Nullabletypes。
如果你有一个int,并决定使它成为一个整数?
int myInt;
你做到了:
int? myInt;
就是现在:
Nullable<int> myInt;
事实上。
在基本的术语中,可以为空的types是普通types的盒装版本,它具有一个名为hasValue的额外布尔字段。 当此字段设置为false时,则该实例为空。
查看这个答案了解CLR实现的更多细节,以及为什么他们可能select了: Boxing / Unboxing Nullable Types – 为什么这个实现?