clr via c# 泛型

1,类型对象,对于应用程序的各种类型创建的对象叫做类型对象:Type object;对于泛型类型参数的类型,CLR同样也会创建内部类型对象,适用于

  • 引用类型
  • 值类型
  • 接口类型
  • 委托类型

具有泛型类型参数的类型称为:开放类型。

指定了泛型实参的类型称为:封闭类型。比如 Dictionary<TKey,TVale>称为开放类型,Dictionary<string,int>称为封闭类型

2,委托和接口泛型的逆变和协变。

  •  Func<object, ArgumentException> fn1 = (x) => { Console.WriteLine(x); return null; };
     Func<string, Exception> fn2 = fn1;
     Exception e = fn2("x");
     Console.ReadKey();
    当一个委托或者一个接口类型,其泛型参数前面带in时,则允许接受该参数为其派生类的委托的实列。
  • 当一个委托或者一个接口类型,其泛型参数前面带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,比较操作==,!= 非法,必须约束为引用类型。因为引用类型的比较时合法的,但是值类型的比较是非法的,除非其重载了==操作符。

posted @ 2020-02-06 15:15  frogkiller  阅读(145)  评论(0编辑  收藏  举报