使用可空类型(Nullable)
可空类型Nullable<T>是.NET Framework 2.0中新增的类型,用它声明的值类型,除了存值之外,还可以表示为null,即该类型的变量可以为空。
下面是Nullable结构的定义:
1namespace System
2{
3 [Serializable]
4 public struct Nullable<T> where T : struct
5 {
6 public Nullable( T value );
7
8 public static explicit operator T( T? value );
9 public static implicit operator T?( T value );
10
11 public bool HasValue { get; }
12
13 public T Value { get; }
14
15 public override bool Equals( object other );
16
17 public override int GetHashCode();
18
19 public T GetValueOrDefault();
20
21 public T GetValueOrDefault( T defaultValue );
22
23 public override string ToString();
24 }
25}
2{
3 [Serializable]
4 public struct Nullable<T> where T : struct
5 {
6 public Nullable( T value );
7
8 public static explicit operator T( T? value );
9 public static implicit operator T?( T value );
10
11 public bool HasValue { get; }
12
13 public T Value { get; }
14
15 public override bool Equals( object other );
16
17 public override int GetHashCode();
18
19 public T GetValueOrDefault();
20
21 public T GetValueOrDefault( T defaultValue );
22
23 public override string ToString();
24 }
25}
从定义可以看出,Nullable<T>结构中的类型参数T必须是一个结构,这就意味着Nullable<T>只支持将值类型用作可空类型,因为引用类型本身就是可空的。另外还可以看出,将值类型(如int)可以隐式地转换为可空类型,而可空类型转换为值类型则要进行显式转换。Nullable<T>还有两个重要的属性:HasValue和Value,前者判断变量内是值还是null,并返回一个布尔值,后者用于取出相应类型的值。很明显如何可空类型的变量此时保存的是null,那么使用Value属性会产生异常(InvalidOperationException)。
使用Nullable<T>声明一个存储int值的可空类型变量,可以这样写:
1Nullable<int> a = null;
这样变量a既可以存储整型值,也可以存储null了。在C#中还有简化的写法:
int? a = null;
这样用起来更加方便。
有了可空类型,那么在从数据库中取值时,如果碰到了NULL值,语句能简化一些,例如,如果不使用可空类型,那么语句可能会这样写:
1if (dataReader["SSN"] == DBNull.Value)
2 ssn = -1; // NULL 用 -1 代替
3else
4 ssn = Convert.ToInt64(dataReader["SSN"]);
2 ssn = -1; // NULL 用 -1 代替
3else
4 ssn = Convert.ToInt64(dataReader["SSN"]);
因为传统的值类型不能为null,所以必须为数据库中的NULL值提供一个无效的值,有时候这个无效的值并不好找。而使用可空类型,变量可以为null,那么我们就可以这样写:
1ssn = dataReader["SSN"] == DBNull.Value ? (long?)null : Convert.ToInt64(dataReader["SSN"]);
在访问可空类型变量中的值时,最好先检查一下HasValue属性,判断一下是否有值,以避免异常发生,例如:
1if (ssn.HasValue)
2{
3 long ssn = (long)ssn; // 或 ssn.Value
4 Console.WriteLine("SSN = {0}", ssn);
5}
2{
3 long ssn = (long)ssn; // 或 ssn.Value
4 Console.WriteLine("SSN = {0}", ssn);
5}
总之,适当地使用可空类型,能够简化代码,减少一些麻烦。
参考文档:
天行健,君子以自强不息。