泛型(四)泛型的同一性

有时候反省语法会将开发人员弄糊涂,因为源代码中可能散布着大量的“<”和“>”符号,这会有损可读性。为了对语法的进行增强,有的开发人员定义了一个新的非泛型类型,他从一个泛型类型派生,并指定了所有类型实参,例如,为了简化下面这样的代码:
 
一些开发人员可能首先定义下面这样一个类:
internal sealed class DateTimeList:List<DateTime>{
    //这里无需放入任何代码
}
然后就可以进行下一步简化创建列表的代码(没有了“<”和“>”符号):
 
DateTimeList dt = new DateTimeList();
 
这样做表面上是方便了(尤其是要为参数、局部变量和字段使用新类型的时候),但是绝对不要单纯的出于增强可读性的目的来定义一个新类,这样会丧失类型同一性(Identity)和相等性(equivalence),如下代码所示:
Boolean sameType=(typeof(List<DateTime>)==typeof(DateTimeList));
 
sameType会被初始化为false,因为比较的是两个不同类型的对象,这也意味着假如一个方法原型(这里指typeof)接受一个DateTimeList,那么不能将一个List<DateTime>传给它。然而,如果方法的原型接受一个List<DateTime>,那么可以将一个DateTimeList传给它,因为DateTimeList是从List<DateTime>派生的。开发人员很容易被所有这一切搞糊涂。
 
幸好,C#提供一种方式,允许使用简化的语法来引用一个泛型封闭类型,同时不会影响类型的相等性:
 
using DateTimeList=System.Collections.Generic.List<System.DateTime>
 
using 指令实际只是定义了一个名为DateTimeList的符号,代码编译时,编译器将代码中出现的所有DateTimeList替换成System.Collections.Generic.List<System.DateTime>。这样就允许开发人员使用一个简化语法,同时不会影响代码的实际含义。所以类型的同一性和相等性得到了维持。
 
还有另一方便,可以使用C#的隐式类型局部变量功能,让编译器根据表达式的类型推断一个方法的局部变量类型:
 
internal sealed class SomeType{
    private static void SomeMethod(){
        //编译器推断出dtl的类型
        var dtl=new List<DateTime>();
    }
}
posted @ 2012-11-26 10:30  Lordbaby  阅读(299)  评论(0编辑  收藏  举报