可空值类型
引用类型的变量可以为空,值类型的变量则不被允许赋值为null,而可空值类型便是可以赋值为null的值类型。
可空值类型的声明与初始化
int? x = null;
int? y = 1;
类型之间的转换
- int转int?总是会成功
int? a = 5; //正确
- int?转int需要显示转换
int c = a; //错误,无法从int?隐式转换为int
int c = (int)a; //正确
- 可空基元类型之间的转型
int? b = null;
//d=5
double? d = 5;
//e=null
double? e = b;
C#对可空值类型应用操作符规则
- 一元操作符(++,+,-,--,!,~):操作数是null,结果就是null
int? a = null;
Console.WriteLine(a++); //null
Console.WriteLine(a + 10); //null
- 二元操作符(+,-,*,/,%,&,|,^,<<,>>):两个操作数其中一个为null,结果就为null。特例:&,|和Boolean?类型的操作数时,情况如下
bool? a = null;
bool? b = true;
Console.WriteLine(a & b); //结果为null
Console.WriteLine(a | b); //结果为true
bool? c = false;
Console.WriteLine(a & c); //结果为false
Console.WriteLine(a | c); //结果为null
- 相等性操作符(==,!=):两个操作数皆为null,两者相等;一个为null,一个不为null,则不等;皆不为null,则比较数值是否相等。
int? a = null;
int? b = null;
int? c = 10;
Console.WriteLine(a == b); //true
Console.WriteLine(a == c); //false
- 关系操作符(<,>,<=,>=):两个操作数任意一个为null,返回false。两个操作数都不是null,就比较值返回结果。
int? a = null;
int? b = null;
int? c = 10;
Console.WriteLine(a > b); //false
Console.WriteLine(a > c); //false
空接合操作符(??)
??:获取两个操作数,如果左边的操作数不为null,则返回左边操作数的值,反之返回右边操作数的值。
int? a = null;
//等价于int b = z.HasValue ? z.Value :123
int b = a ?? 123;
Console.WriteLine(b); //结果为123
int? c = 3;
Console.WriteLine(c ?? 123); //结果为3
可空值类型的装箱与拆箱
- 装箱:CLR对可空值类型装箱时,如果实例为null,不装箱任何东西,并返回null,否则(以int?为例)则会装箱一个Int32的值
int? a = null;
object o = a;
Console.WriteLine(o == null); //true
a = 1;
o = a;
Console.WriteLine(o); //结果为1
Console.WriteLine(o.GetType()); //输出System.Int32
- 拆箱:如果已装箱值类型的引用是null,将其拆箱成一个可空值类型(T?),CLR会直接将T?的值设为null
object o = null;
//a=null
int? a = (int?)o;
Console.WriteLine(a == null); //输出true
//引发System.NullReferenceException异常
int b = (int)o;
可重载自定义值类型的操作符方法,从而让编译器正确对待它
struct Position
{
private int m_X, m_Y;
public Position(int x, int y)
{
this.m_X = x;
this.m_Y = y;
}
public static bool operator ==(Position pos1, Position pos2)
{
return (pos1.m_X == pos2.m_X) && (pos1.m_Y == pos2.m_Y);
}
public static bool operator !=(Position pos1, Position pos2)
{
return (pos1.m_X != pos2.m_X) || (pos1.m_Y != pos2.m_Y);
}
}
static void Main(string[] args)
{
Position? pos1 = new Position(1, 2);
Position? pos2 = new Position(3, 4);
Position? pos3 = new Position(3, 4);
Console.WriteLine(pos1 == pos2); //false
Console.WriteLine(pos1 != pos2); //true
Console.WriteLine(pos2 == pos3); //true
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。