可空类型Nullable Types
引用类型通过使用Null引用就可以表示一个不存在的值。
Reference types can represent a nonexistent value with a null reference.
然而,值类型通常就无法表示空值了。
Value types,however, cannot ordinarily represent null values.
要在值类型里表示null值,你必须使用一种特殊的构造,它叫做可空(值)类型
To represent null in value type,you must use a special construct called a nullable type.
可空值类型是这样表示的:前面就是一个值类型,他后面跟着一个?(问号)
A nullable type is denoted with a value type followed by the ? symbol
Nullable
- T?这种写法表示的可空类型会被翻译成System.Nullable
.而System.Nullable 是一种轻量级不可变的结构,它只有两个字段(Value和HasValue),这两个字段分别表示真正的值(如果不是Null的话)和是否有非Null值。
int? i = null;
Console.WriteLine(i == null);
会被翻译成
Nullable<int> i = new Nullable<int>();
Console.WriteLine(!i.HasValue); // True
无参的GetValueOrDefault()方法在HasValue为True的时候,会返回结构体里的值,如果HasValue为false,那么返回该类型的默认值。
- 有参的GetValueOrDefault(T defaultvalue)方法,在HasValue为false的情况下,会返回结构体里面的值或者通过方法参数指定的这个默认值。
- objec里面定义的Equals(object)和GetHashCode()这两个方法也被相应的重写了,首先会比较HasValue属性的值,如果两个被比较对象的HasValue属性都是true,那么然后就会比较Value属性的相等性。
- 如果在HasValue为false的情况下,想去尝试获取Value的值,那么就会抛出InvalidOperationException
- 如果HasValue为true的话,那么GetValueOrDefault()方法就会返回该类型真正的值;否则的话,它会返回new T()或者是指定的自定义默认值。
- T?默认值是null。
Nullable的简化版源码
public struct Nullable<T> where T : struct
{
private readonly T value;
private readonly bool hasValue;
public Nullable(T value)
{
this.value = value;
this.hasValue = true;
}
public bool HasValue { get { return hasValue; } }
public T Value
{
get
{
if (!hasValue)
{
throw new InvalidOperationException();
}
return value;
}
}
}
- 这里已声明的构造函数把hasValue这个字段值设为了true。
- 和其他结构体一样,它也有一个隐式的无参构造函数。在哪里hasValue的值原封不动,就是false;而value的值就是T的默认值。
- 以上代码中,作用于Nullable
的where T:struct这个约束,它允许T可以使任意的值类型,但不可以是Nullable . - 下面这些都是不合法的:
- Nullable
(string是引用类型) - Nullable
(数组是引用类型) - Nullable
(Enum本事不是值类型) - Nullable
>(Nullable 是可空的) - Nullable
>>(嵌套着用也不行!。。)
- Nullable