1. 可空类型
值类型是不可以为null的[即不可为空值], 假如我们想让它为null呢[比如它对映这数据库中的某个表的某个字段,但是这个字段是null]。 自己实现的话,简单的写一个类,有一个值类型的字段,检查该字段是否初始化,是的话返回该值,否的话返回null。 假如是在C#1.0时,那么每个值类型都要写这么一份代码了。C#2.0有了泛型的支持,所以我们可以定义一个泛型版的。 幸运的是C#2.0带来了一个新的类型[System.Nullable<T>]帮我们实现了,T就是需要传入的类型[约束为值类型]. 比如:
Nullable<int> i=null; //简写? int? i=null;
下面是System.Nullable<T>泛型类原型:
1 [Serializable]//表示了序列化 2 public struct Nullable<T> where T : struct 3 { 4 //构造器,初始化类型参数T 5 public Nullable(T value); 6 //重载类型转换操作符<显示转换:int i=(int)Nullable<int>类型变量> 7 public static explicit operator T(T? value); 8 //重载类型转换操作符<隐式转换:int? i=int类型变量> 9 public static implicit operator T?(T value); 10 //判断是否是null, 11 public bool HasValue { get; } 12 //如果不是null,取得值 13 public T Value { get; } 14 //重写Equals 15 public override bool Equals(object other); 16 //重写GetHashCode 17 public override int GetHashCode(); 18 //如果HasValue属性为true,返回Value属性的值 19 //否则返回当前 Nullable<T> 对象<类型是T>的默认值 20 //即使 HasValue属性为false,GetValueOrDefault方法也会返回一个值 21 //(这与 Value 属性不同,该属性将引发异常)。 22 public T GetValueOrDefault(); 23 //同上,参数是指定的默认值,如果int? i=null; 24 //int j=i.GetValueOrDefault(10);则j的值为10 25 public T GetValueOrDefault(T defaultValue); 26 //重写ToString 27 public override string ToString(); 28 }
各个方法使用DEMO:
static void Main() { Nullable<int> i = null; int l = i.GetValueOrDefault();//l=0 int n = i.GetValueOrDefault(10);//j=10 int h = i.HasValue ? i.Value : default(int);//h=0 int m = 100; i = m;//隐式转换 m = (int)i;//显示转换 Console.WriteLine(i.Equals(m));//true Console.WriteLine(i.GetType());//System.Int32 Console.WriteLine(i.ToString());//100 }
现在做些运算:
static void Main() { Nullable<int> i = 1; int? j = 2; //执行运算之前会先调用HasValue属性 int l = (int)(i + j); Console.WriteLine(l);//3 i = null; //抛出异常System.InvalidOperationException //其中一个为null则结果就为null,所以null无法转换为int int n = (int)(i + j); Console.WriteLine(n); }
它的这些运算还是蛮繁琐的,先检查是否为null,如果都不是null,再取得各自的值在运算,否则返回null。 不是迫不得已的情况下最好不使用[效率不怎么好]。
2. 静态类
静态类是只用于包含静态成员,它既不能实例化,也不能被继承。 它相当于一个sealed abstract类[查看IL代码实际上静态类就是被标识为sealed和abstract]。 相当于提供一些功能性的全局函数[C#不支持全局函数,但是CLR支持,IL支持,这算是一种变相的实现全局函数吧]。
静态类不能有实例构造器;
静态类不能有任何实例成员;
静态类上不能使用abstract或sealed修饰符;
静态类默认继承自System.Object根类,不能显式指定任何其他基类[实际上也没有什么意义的];
静态类不能指定任何接口实现。;
静态类的成员不能有protected 或 protected internal访问保护修饰符[这些都是供子类访问的,但是静态类不允许被继承,所以你用这些访问修饰符没有任何意义]。