泛型系列<6>:创建一个可以被初始化为空的值类型
2011-12-02 00:02
260 查看
4.7 创建一个可以被初始化为空的值类型
问题
您有一个数字类型的变量,用于控制从数据库中获取的数值。数据库可能为这个值返回一个null值。您需要一个简洁的方法来存储这个数值,甚至它返回为null。
解决方案
使用可空类型。有两个创建可空类型的方法。第一种方法是使用?类型修饰符:
int? myDBInt = null;
第二种方法是使用Nullable<T>泛型类型:
Nullable<int> myDBInt = new Nullable<int>();
讨论
本质上,下面两个声明是等价的:
int? myDBInt = null;
Nullable<int> myDBInt = new Nullable<int>();
两个声明中,myDBInt都被认为是可空类型并初始化为null。一个可空类型实现了InullableValue接口,它只有两个属性成员:HasValue和Value。如果把可空类型设置为null,HasValue属性将返回false,否则将返回true。如果HasValue返回true,就可以访问Value属性以获得可空数据类型里当前存放的值。如果引发了InvalidOperationException异常,这是因为此时Value属性还未被定义。
另外,测试可空类型可以有两种方法。第一,使用HasValue属性如下:
if (myDBInt.HasValue)
Console.WriteLine("Has a value: " + myDBInt.Value);
else
Console.WriteLine("Does not have a value (NULL)");
第二种方法是跟null对比:
if (myDBInt != null)
Console.WriteLine("Has a value: " + myDBInt.Value);
else
Console.WriteLine("Does not have a value (NULL)");
两种方法都可以让人接受。
当需要把可空类型转换为非可空类型时,转换操作将正常进行,如果可空类型被设置为null就会引发一个InvalidOperationException异常。当把一个非可空类型转换为可空类型时,转换操作将正常运行,不会引发InvalidOperationException异常,非可空类型永远不会为null。
需要提防的是可空类型在进行比较运算的时候。例如执行下列代码时:
if (myTempDBInt < 100)
Console.WriteLine("myTempDBInt < 100");
else
Console.WriteLine("myTempDBInt >= 100");
“myTempDBInt < 100”这句代码明显有错。为了修正它,您不得不检查myTempDBInt是否为空。如果不是,才能执行if语句里的代码块:
if (myTempDBInt != null)
{
if (myTempDBInt < 100)
Console.WriteLine("myTempDBInt < 100");
else
Console.WriteLine("myTempDBInt >= 100");
}
else
{
// 在这里处理空值
}
另外一个有趣的事情是您可以象使用一般数字类型一样使用可空类型,如:
int? DBInt = 10;
int Value = 2;
int? Result = DBInt + Value; // Result == 12
如果表达式中的可空类型是一个null值,则表达式的结果为null,但如果没有可空类型的值为null,运算符会把它当成一般类型。如上例中的DBInt为null,则Result的结果也为null。
相关文章推荐
- 泛型系列<8>:使用泛型创建只读集合
- 无法跨越程序集边界使用程序集“DataCheck, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中的类型“List<ILayer>”,因为该类型有一个为嵌入互操作类型的泛型类型参数
- ArrayList<Integer> list = new ArrayList<Integer>();在这个泛型为 Integer 的 ArrayList 中存放一个 String 类型的对象。
- ArrayList<Integer> list = new ArrayList<Integer>(); 在这个泛型为Integer的ArrayList中存放一个String类型的对象。
- 类型“string”必须是不可以为 null 值的类型才能用作泛型类型或方法“System.Nullable<T>”中的参数“T”
- 【C#】对异步请求处理程序IHttpAsyncHandler的理解和分享一个易用性封装 【手记】走近科学之为什么明明实现了IEnumerable<T>的类型却不能调用LINQ扩展方法 【手记】手机网页弹出层后屏蔽底层的滑动响应 【手记】ASP.NET提示“未能创建类型”处理 【Web】一个非常简单的移动web消息框 【手记】解决EXCEL跑SQL遇“查询无法运行或数据库表无法打开...”
- 泛型系列<2> 创建泛型类
- 泛型系列<3>:获取泛型的类型
- 使用泛型类型System.Collections.Generic.Icomparer &lt;T&gt; 需要一个类型参数
- 泛型系列<4>使用相应的泛型版本替换Stack和Queue
- 将一个DataTable转换成一个List<T>的泛型集合
- <读书笔记>JavaScript系列之7种创建对象(面向对象)
- 泛型约束where条件的使用(可以通过类型参数动态反射创建实例)
- 泛型系列<7>反转Sorted List里的内容
- mybatis在<if>中传入一个简单类型参数的两种写法。
- Linq系列(2)——类型推断,IEnumerable<T>和IQueryable<T>
- 类型“string”必须是不可为 null 的值类型才能用作泛型类型或方法“System.Nullable<T>”中的参数“T”
- Cassandra key说明——Cassandra 整体数据可以理解成一个巨大的嵌套的Map Map<RowKey, SortedMap<ColumnKey, ColumnValue>>
- 实战c++中的vector系列--vector<unique_ptr<>>初始化(全部权转移)
- 【技术】创建一个 <input> 元素,同时设定 type 属性、属性值,以及一些事件