中国建设厅网站首页,个人站长做什么网站好,做采集网站难不,深圳品牌策划第十二章 泛型 泛型#xff1a;支持泛型值类型、泛型引用类型、泛型接口、泛型委托#xff1b;允许在引用类型、值类型和接口中定义泛型方法#xff1b;泛型参数变量要么称为T#xff0c;要么以T开头 具有泛型类型参数的类型称为开放类型#xff0c;不允许构造实例#…第十二章 泛型 泛型支持泛型值类型、泛型引用类型、泛型接口、泛型委托允许在引用类型、值类型和接口中定义泛型方法泛型参数变量要么称为T要么以T开头 具有泛型类型参数的类型称为开放类型不允许构造实例当为所有参数类型传递了实际参数类型就称为封闭类型允许构造实例 泛型类型是类型所以可以从其他类型派生使用泛型类型并指定形参时实际是定义一个新的类型从泛型类型派生自的类型派生。例ListT派生自Object所以Liststring也派生自Object 泛型的同一性(不想让符号降低可读性时的处理) 使用class dtl : ListDateTime会失去同一性typeof(dtl) ! typeof( ListDateTime)可以使用 using dtl System.Collections.Generic.ListDateTime可以直接var dtl new ListDateTime 代码爆炸CLR每新出现一种类型的实参都要编译一次代码 不同程序集中同一类型只编译一次限定同一个domain所有引用类型都视为同一种实参所有引用类型只编译一次 可以定义泛型接口如IEnumeratorT 可以定义泛型委托如ActionT 泛型类型参数的逆变和协变 逆变性用in关键字标记的泛型参数可以更改为它的派生类输入 协变性用out关键字标记的泛型参数可以更改为它的基类输出 例定义public delegate TResult Funcin T, out TResult(T arg); FuncObject, ArgumentException fn1 null, FuncString, Exception fn2 fn1 是合法的因为String从Object派生Exception是ArgumentException的基类 使用Exception e fn2( ) ; 实参String-Object, 返回值ArgumentException-Exception 委托和接口都可以将类型参数标记为逆变量和协变量 泛型方法定义泛型类、结构或接口时类中定义的方法可以使用类指定的类型参数 例:定义了class SomeClassT, 类中的方法可以使用类指定的T如定义public T SomeMethodT() 由于out/ref实参传递的变量必须具有与方法参数相同的类型所以可以使用泛型实现。 例:private static void SwapT(ref T o1, ref T o2); C#编译器在调用泛型方法时可以进行类型推断在可以确定类型实参的情况下可以不用指定 属性、索引器、事件、操作符方法、构造器、终结器本身不能有类型参数但是可以在泛型类中定义从而使用泛型类的类型参数 泛型可验证性编译代码时需要确定代码适用于当前或已有或将来可能定义的任何类型比如调用T.ToString(),对所有类型都有ToString()方法所以代码合法 使用where关键字指定约束 约束可以应用于泛型类和泛型方法不能用于重载不能基于类型参数名称或约束重载也不允许为重写方法的类型指定约束主要约束主要约束指非密封类的一个引用类型不包括Object, Array, Delegate, MulticastDelegate, ValueType, Enum, Void能有零个或一个特殊主要约束class指引用类型struct指值类型次要约束指接口类型能有零个或多个构造器约束指拥有公共无参构造器的非抽象类型 其他可验证性问题 不能将泛型变量转型为其他变量除非转成与约束兼容的类型不能将泛型变量设为null除非泛型类型被约束成引用类型可以将泛型类型变量与null比较或!虽然值类型不能与null比较因为永远不会null但是约束成值类型后代码能通过编译但不执行if逻辑只生成永远为true的分支的代码同一泛型类型的两个变量如果不能肯定是引用类型则不能比较T a,b;判断 ab不能将操作符、-、*、/用于泛型变量不能编译