CLR via C# 学习笔记----Nullable Value Types可以指定为Null的值类型
Nullable Value Types
据你所知,一个值类型的变量不可能是Null的,他统称包含了一个值类型的类型本身。事实上,这就是为什么我们管值类型叫做值类型。不幸的是,有很多情况会有些问题。例如,当你设计这个数据库的类型的时候,可以定义一个列的数据类型是32bit的整型数而对应FCL中的Int32类型。但是,这一列在数据库中暗示着可能为空,就意味着这一列的数据为空是可以接受的。但是使用.NET Framework 来操作数据库中的数据是很困难的因为CLR不允许int32 的值为空的这一种表现形式。
这有一个Java的例子,java.util.Date类是一个引用类型,因此这个类型可以被置为null.
但是,在CLR中,System.DateTime是一个值类型,DateTime变量是永远不能为空的。如果一个应用程序使用Java来写的并且打算与CLR运行的一个Webservice进行雍熙,那么这里就会有一个问题了。如果Java的应用程序发送一个null因为CLR没有办法呈现并且对它进行操作。
为了改进这个形式,微软增加了一个Nullable类型的变量在CLR中。为了明白这是怎么工作的,我们现在必须看看FCL中定义的System.Nullable<T>这个类。这里可以逻辑上表现一下System.Nullable<T>类型是如何定义的:
[Serializable]
public struct Nulllable<T> where T : struct
{
private Boolean hasValue = false;
internal T value = default(T);
public void Nullable(T value)
{
this.value = value;
this.hasValue = true;
}
public Boolean HashValue
{
get { return this.hasValue; }
}
public T Value
{
get
{
if (!hasValue)
{
throw new InvalidCastException("nullable Object mush have a value");
}
return value;
}
}
public T GetValueOrDefault()
{
return value;
}
public T GetValueOrDefault(T defaultValue)
{
if (!HashValue)
return defaultValue;
return value;
}
public override bool Equals(object other)
{
if (!HashValue)
return (other == null);
if (other == null)
return false;
return value.Equals(other);
}
public override int GetHashCode()
{
if (!HashValue)
return 0;
return value.GetHashCode();
}
public override string ToString()
{
if (!HashValue) return "";
return value.ToString();
}
public static implicit operator Nullable<T>(T value)
{
return new Nullable<T>(value);
}
public static explicit operator T(Nullable<T> value)
{
return value.Value;
}
}
}
正如你所见,这个类压缩了值类型的概念同样可以是null。由于Nullable<T>它本身就是一个值类型,它的实体同样是一个轻量级。这就是说,实例同样可以在stack上面,同时实例比初始的值类型加上Boolean类型的大小。注意Nullable类型的变量T,仅限于Struct中,因为引用类型变量可以置为null了。所以现在,如你你想要使用nullavle int32在你的代码中,可以像如下这么写:
Nullable <Int32> x = 5;
Nullable <Int32> y = null;
Cosole.WriteLine(“x:HasValue = {0}, Value={1}”,
x.HasValue, x.Value);
Console.WriteLine(“y: HasValue={0},Value={1},
y.HasValue, y.GetValueOrDefault());
C# Support for Nullable Value Types(C#对Nullable类型的支持)
事实上,C#小组想要整合nullable类型在C#语言中,使他们成为头等公民。其目的就是C# 提供了一个在nullable工作的符号。C#允许代码声明初始化的x和y变量是这样被声明的:
Int32? X = 5;
Int32? Y = null;
在C#中,Int32?是一个Nullable<Int32> 的概念。但是C#比这个深入。C#允许你对null类型的转换。如下显示了例子:
Int32? A = 5;
Int32? B = null;
//一些实际情况。
Int32? a = 5;
Int32? b = null;
Int32? c = (Int32)a;
Double? d = 5;
Double? e = b;
a++;//a = 6
b = -b;//b = null
a = a + 3; // a = 9
b = b * 3; // b = null;
if (a == null) { } else { }
if (b == null) { } else { }
if (a != b) { } else { }
if (a < b) { } else { }
如下显示了一些操作符的计算方式:
l (+ ++ = == ! ~) 一元的 如果开始null,结果还是null
l (+ - * / % & | ^ << >>) 二元的,一个是null,另一个也是null
l ( == !=). =运算符,如果操作数都是null的话,那么他们相等。如果一个是null,那么不想等。如果都不是null,那么比较数值大小再返回是否相等。
l (< > <= >=)比较运算符,如果一个是null,返回false。如果都不是null,那么比较数值大小。再返回。
C# 中的 Null-Coalescing 操作符。
C#中有一个操作符是这样的(??),需要两个操作数。如果左面的操作数不为null,那么返回左面的操作数。如果左边的操作符为空的话,那么返回右边的操作符。这个(??)操作符非常方便,可以红来设置变量的初始值。
private static void NullCoalescingOperator()
{
Int32? b = null;
Int32? x = b ?? 123;
Console.WriteLine(x);
string temp = GetFilename();
filename = (temp != null) ? temp : "Untitled";
string filename = GetFilename() ?? "Untitled";
}
CLR 对Nullable值类型有特殊的支持
CLR的特殊支持提供了装箱,拆箱和GetType,并且调用接口方法,并且这个给Nullable类型使得更适合CRL。对程序员来说会表现的更加的自然,更好的能够接受。
-
Nullable类型的装箱
假想下,Nullable<Int32> 被设置为空,如果这个变量当作方法原型的参数是一个Object传递,那么这个变量必须要装箱。如果一个引用类型被包装成Nullable<Int32>传递给一个方法,这不是一个理想的,因为这个方法需要传递一个非空的,诚然Nullalbe<Int32>变量在逻辑上包含一个null的值。为了修改这个,CLR执行一些特殊的代码当装箱一个非空的变量去说明nullable类型在环境中是一级的公民。
特别的,当CLR对一个Nullable<T>实例进行装箱的时候,它会检查它是否为空。如果为空的话,CLR事实上不会做任何事情,并且把null返回。如果这个实例不是空的话,那么CLR把这个实例提取出来并且装箱。换句话说就是,一个Nullalbe<Int32>的值是5并且装箱为一个Int32的值。
Int32? N = null;
Object o = n;
Console.WriteLine (“o is null = {0}” ,o == null); //ture
N = 5;
O = n;
Console.WriteLine(“o’s type={0}”, o.GetType()); // System.Int32
-
Nullable类型拆箱
Object o = 5;
Int32? A = (Int32?) o; // a =5
Int32? B = (Int32) o; //b=5
O = null;
A = (Int32?) o; //a = null
B = (Int32) o; // NullReferenceException.
作者:Alexliu(alex dotNet Learning)
出处:http://alexliu.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,转载请注明。并且保留文章链接。否则保留追究法律责任的权利。