[C#2] 4-可空类型、静态类

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访问保护修饰符[这些都是供子类访问的,但是静态类不允许被继承,所以你用这些访问修饰符没有任何意义]。

posted @ 2011-04-06 19:23  Timetombs  阅读(1057)  评论(0编辑  收藏  举报