可为空的值类型(Nullable<T>)需要注意的地方
2011-02-15 19:10
260 查看
值类型是不可以被赋值为null的,但有时候我们却需要简单的值类型被设置为null,比如一个查询界面上有很多的查询条件,查询条件可以使用也可以留空,这是从UI收集查询参数信息传递到后台执行查询的时候,我们如果约定某个参数为null时,就认为用户没有使用该查询参数。
第一,它是一个结构类型,值类型
其实下面的这个变量声明就是可为空的值类型
但是number是真的值类型吗,我们使用typeof(int?)看看他的类型吧,
System.Nullable`1[System.Int32]
Nullable<T>的声明如下:
声明很清楚是Struct,这样我们就明白了,原来int?是值类型啊。
为了验证,我们使用number.GetType()来看看类型是什么,答案是System.Int32。
所以,能被赋值为null的,不一定是引用类型啊。(注:CLR本身并不支持值类型被赋值为null,最多是将每个bit都设置为0。之所以现在能够被赋值为null,是因为编译器帮我们做了转换,使得C#语法支持了这种情况。这也是回复的网友说的语法糖(Syntacticsugar))
下面的代码在控制台中打印的结果是100,而不是101:
另外,大家看看下面这个代码行:
number变量的值居然是null。
有的朋友会说Nullable<T>是结构类型,所以装箱和拆箱是符合值类型特点的,我认为这句话是错误的。
比如:
a是可以被拆箱为null值的,而b这行代码运行时是要抛出NullReferenceException异常的。
第二,Nullable<T>可以转换为接口类型
本身Nullabe没有实现任何接口,但是请看下面的代码段:
这是CLR为开发人员提供的福利啊,呵呵。
如果没有这个福利的话,我们就写出下面的代码才能实现同样的过程:
第三,??操作符
顺便提提这个??(null-coalescingoperator)操作符,当操作符左边的表达式为空时,返回操作符右边的值;如果操作符左边表达式值不为空时,返回操作符左边表达式值。
??操作符给我们的编码带来了很多的便利,是我们的代码更为简练,可读性更强,看下面几个示例:
还可以连写:
还可以用在Lamda表达式里面,增强可读性:
上面这些东西,希望对大家有用。
第一,它是一个结构类型,值类型
其实下面的这个变量声明就是可为空的值类型
int?number=100;
但是number是真的值类型吗,我们使用typeof(int?)看看他的类型吧,
System.Nullable`1[System.Int32]
Nullable<T>的声明如下:
publicstructNullable<T>whereT:struct
声明很清楚是Struct,这样我们就明白了,原来int?是值类型啊。
为了验证,我们使用number.GetType()来看看类型是什么,答案是System.Int32。
所以,能被赋值为null的,不一定是引用类型啊。(注:CLR本身并不支持值类型被赋值为null,最多是将每个bit都设置为0。之所以现在能够被赋值为null,是因为编译器帮我们做了转换,使得C#语法支持了这种情况。这也是回复的网友说的语法糖(Syntacticsugar))
下面的代码在控制台中打印的结果是100,而不是101:
publicvoidTest() { int?number=100; ChangeValue(number); Console.WriteLine(number); } voidChangeValue(int?number) { number+=1; }
另外,大家看看下面这个代码行:
int?number=newNullable<int>();
number变量的值居然是null。
有的朋友会说Nullable<T>是结构类型,所以装箱和拆箱是符合值类型特点的,我认为这句话是错误的。
比如:
objecto=null; int?a=(int?)o; intb=(int)o;
a是可以被拆箱为null值的,而b这行代码运行时是要抛出NullReferenceException异常的。
第二,Nullable<T>可以转换为接口类型
本身Nullabe没有实现任何接口,但是请看下面的代码段:
Int32?n=5; Int32result=((IComparable)n).CompareTo(5);//Compiles&runsOK Console.WriteLine(result);//0
这是CLR为开发人员提供的福利啊,呵呵。
如果没有这个福利的话,我们就写出下面的代码才能实现同样的过程:
Int32result=((IComparable)(Int32)n).CompareTo(5);
第三,??操作符
顺便提提这个??(null-coalescingoperator)操作符,当操作符左边的表达式为空时,返回操作符右边的值;如果操作符左边表达式值不为空时,返回操作符左边表达式值。
??操作符给我们的编码带来了很多的便利,是我们的代码更为简练,可读性更强,看下面几个示例:
privatestaticvoidNullCoalescingOperator(){
Int32?b=null;
//Thelinebelowisequivalentto:
//x=(b.HasValue)?b.Value:123
Int32x=b??123;
Console.WriteLine(x);//"123"
//Thelinebelowisequivalentto:
//Stringtemp=GetFilename();
//filename=(temp!=null)?temp:"Untitled";
Stringfilename=GetFilename()??"Untitled";
}
还可以连写:
Strings=SomeMethod1()??SomeMethod2()??"Untitled";
还可以用在Lamda表达式里面,增强可读性:
Func<String>f=()=>SomeMethod()??"Untitled";
上面这些东西,希望对大家有用。
相关文章推荐
- Int? 代表什么意思, 可为空的值类型(Nullable<T>)需要注意的地方
- 把二分查找算法写正确需要注意的地方<转>
- ACE_Message_Queue<ACE_MT_SYNCH>::putq ()使用时需要注意的地方
- Socket:java与C之间的文件传送<3>(JAVA与C通信需要注意的地方)
- Socket:java与C之间的文件传送<3>(JAVA与C通信需要注意的地方)
- struts.xml中<package ...>需要注意的地方
- enum类型被intent所携带时需要注意的地方
- 谈谈Nullable<T>的类型转换问题
- 类型“string”必须是不可为 null 的值类型才能用作泛型类型或方法“System.Nullable<T>”中的参数“T”
- 以模板的方式重载"operator <<"需要注意的地方
- 从数据库取出的Date类型的数据放入Map<String,Object>之前需要做的处理
- 在PostgreSQL中使用日期类型时一些需要注意的地方
- <2012 12 05> 在U-boot上用tftp进行文件传输需要注意的地方
- J2EE初学者需要注意的问题 <转>
- Oracle日期类型Date和timestamp需要注意的地方
- 如何建立mysql索引、介绍mysql的索引类型,mysql索引的利与弊,以及建立索引时需要注意的地方
- 【SpringMVC】<context:include-filter>和<context:exclude-filter>使用时要注意的地方 在Spring MVC中的配置中一般会遇到这两个标签,作
- 细说Nullable<T>类型
- asp.net MVC:CheckBoxFor 绑定 nullable<bool> 类型
- 谈谈Nullable<T>的类型转换问题