可空值类型

援用类型的变量能够为空,值类型的变量则不被容许赋值为null,而可空值类型便是能够赋值为null的值类型。

可空值类型的申明与初始化
int? x = null;int? y = 1;
类型之间的转换
  • int转int?总是会胜利
int? a = 5;     //正确
  • int?转int须要显示转换
int c = a;      //谬误,无奈从int?隐式转换为intint c = (int)a; //正确
  • 可空基元类型之间的转型
int? b = null;//d=5double? d = 5;//e=nulldouble? e = b;
C#对可空值类型利用操作符规定
  • 一元操作符(++,+,-,--,!,~):操作数是null,后果就是null
int? a = null;Console.WriteLine(a++);     //nullConsole.WriteLine(a + 10);  //null
  • 二元操作符(+,-,*,/,%,&,|,^,<<,>>):两个操作数其中一个为null,后果就为null。特例:&,|和Boolean?类型的操作数时,状况如下
bool? a = null;bool? b = true;Console.WriteLine(a & b);   //后果为nullConsole.WriteLine(a | b);   //后果为truebool? c = false;Console.WriteLine(a & c);   //后果为falseConsole.WriteLine(a | c);   //后果为null
  • 相等性操作符(==,!=):两个操作数皆为null,两者相等;一个为null,一个不为null,则不等;皆不为null,则比拟数值是否相等。
int? a = null;int? b = null;int? c = 10;Console.WriteLine(a == b);  //trueConsole.WriteLine(a == c);  //false
  • 关系操作符(<,>,<=,>=):两个操作数任意一个为null,返回false。两个操作数都不是null,就比拟值返回后果。
int? a = null;int? b = null;int? c = 10;Console.WriteLine(a > b);   //falseConsole.WriteLine(a > c);   //false
空接合操作符(??)

??:获取两个操作数,如果右边的操作数不为null,则返回右边操作数的值,反之返回左边操作数的值。

int? a = null;//等价于int b = z.HasValue ? z.Value :123int b = a ?? 123;Console.WriteLine(b); //后果为123int? c = 3;Console.WriteLine(c ?? 123); //后果为3
可空值类型的装箱与拆箱
  • 装箱:CLR对可空值类型装箱时,如果实例为null,不装箱任何货色,并返回null,否则(以int?为例)则会装箱一个Int32的值
int? a = null;object o = a;Console.WriteLine(o == null); //truea = 1;o = a;Console.WriteLine(o); //后果为1Console.WriteLine(o.GetType()); //输入System.Int32
  • 拆箱:如果已装箱值类型的援用是null,将其拆箱成一个可空值类型(T?),CLR会间接将T?的值设为null
object o = null;//a=nullint? 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}