1,类型对象,对于应用程序的各种类型创建的对象叫做类型对象:Type object;对于泛型类型参数的类型,CLR同样也会创建内部类型对象,适用于
- 引用类型
- 值类型
- 接口类型
- 委托类型
具有泛型类型参数的类型称为:开放类型。
指定了泛型实参的类型称为:封闭类型。比如 Dictionary<TKey,TVale>称为开放类型,Dictionary<string,int>称为封闭类型
2,委托和接口泛型的逆变和协变。
- 当一个委托或者一个接口类型,其泛型参数前面带in时,则允许接受该参数为其派生类的委托的实列。
Func<object, ArgumentException> fn1 = (x) => { Console.WriteLine(x); return null; }; Func<string, Exception> fn2 = fn1; Exception e = fn2("x"); Console.ReadKey();
- 当一个委托或者一个接口类型,其泛型参数前面带out时,则允许接受该参数为其基类的委托的实列。比如上面。
- string 是 object 的派生类,Exception 是 ArgumentException 的基类。所以可以赋值。
3,泛型的约束
public static T Min<T>(T o1,T o2 ) where T : IComparable<T> { if (o1.CompareTo(o2) < 0) return o1; return o2; } public static void CallMin() { object o1 = "jeff", o2 = "Richter"; object oMin = MinType.Min<string>((string)o1, (string)o2); }
利用约束,则在泛型函数内部可以使用约束特有的性质
- 类型参数,可以指定0个或者多个主要约束,组要约束不可以是,Object,Array,Delegate,ValueType,Enum,Void
- 特殊的类型:class--表明是引用类型,则可以赋值 null;struct---值类型,支持default(T);支持 new T();
- 特殊的类型:new()---则支持 new()操作构造器约束
private static List<TBase> ConvertIList<T, TBase>(IList<T> list) where T : TBase { List<TBase> baseList = new List<TBase>(list.Count); for (int index = 0; index < list.Count; index++) { baseList.Add(list[index]); } return baseList; } public static void CallingConvertIList() { IList<String> ls = new List<string>(); ls.Add("a string"); //1,将IList<string> 转换为 IList<Object> IList<object> l1 = ConvertIList<string, object>(ls); //2,将Ilist<string>转换为IList<IComparable> IList<IComparable> l2 = ConvertIList<string, IComparable>(ls); //3,将Ilist<string>转换为IList<Exception> IList<Exception> l3 = ConvertIList<string, Exception>(ls); }
l3的时候,失败,应为不能进行类型的转换。
4,泛型变量的类型引用
//方法1: private void Cast<T>(T obj) { int x =(int)obj;//错误,不允许 int x =(int)(object)obj//允许,但是可能会在运行时报错 string x= obj as string;//允许,在引用类型时候 }
5,将泛型类型变量设为默认值,如果是7引用类型,则设为null,如果是值类型,则设为0.
T temp = default(T);
6,将泛型类型和null进行比较。允许,但是当T约束为struct时,不允许。
7,比较操作==,!= 非法,必须约束为引用类型。因为引用类型的比较时合法的,但是值类型的比较是非法的,除非其重载了==操作符。