zoukankan      html  css  js  c++  java
  • C#泛型基础

    1. 泛型是C#2.0中新加入的特性,它增强了性能,使代码更富有表现力,提供了更好的通用化方案,在早期的C#版本中通用化是通过类型与通用基类型Object之间进行强制转换来实现的,泛型针对这种限制提供了解决方案,而且更它将大量的安全检查从执行时转移到了编译时进行.C#中可以创建自己的泛型接口,泛型类,泛型方法,泛型事件和泛型委托,但不存在泛型的属性,索引器,操作符,构造函数和析构器。
    2. 类型参数的约束
      约束 说明

      T:Struct

      类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。有关更多信息,请参见使用可空类型(C# 编程指南)

      T:Class

      类型参数必须是引用类型,包括任何类、接口、委托或数组类型。

      T:new()

      类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。

      T:基类名

      类型参数必须是指定的基类或派生自指定的基类。

      T:接口名称

      类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。

      T:U

      为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束。

    3. 泛型类型是可以重载的,如MyType,Mytype<T>,MyType<T,U>,这些都是不同的类型,他们之间不能相互转换,这一点对泛型方法也是成立的,
      //在同一个类中
      void DoWork() { }
      void DoWork<T>() { }
      void DoWork<T, U>() { }
      泛型类的构造函数没有尖括号,
      Dictionary泛型类
    4. 泛型方法类型实参的类型推断:类型推断只适用于泛型方法,不适用于泛型类型,
      static List<T> MakeList<T>(T first,T second)
      。。。
      List<string>list  = MakeList<string>("tom","Jerry");
      //使用类型推导可以写成
      List<string>list=MakeList("tom","Jerry")
      对于泛型类可以在类中定义一个泛型方法实现类型推导
      public seale class Pair<T1,T2>:IEquatable<Pair<T1,T2>>
      {
       。。。
      public static Pair<T1,T2>Of<T1,T2>(T1 first,T2 second)
      {
      return new Pair<T1,T2>(first,second);
      }
      }
    5. 泛型中的协变性,逆变性和不变性:
      • 协变性:泛型类型参数可以从派生类转换为基类,这种变化时和谐的。通常对于委托,协变类型参数可用作委托的返回类型,对于接口,协变类型参数可以用作接口的方法的返回类型。支持协变性的接口有IEnumerable<T>,IEnumerator<T>,IQueryable<T>,IGrouping<TKey,TElement>
      • 逆变性:泛型类型参数可以从基类隐式转换为派生类。通常对于委托,逆变参数可用作参数类型,对于接口逆变类型参数可用作接口方法的参数类型,支持逆变性的接口有IComparer<T>,IComparable<T>和IEqualityComparer<T>
      • 不变性:表示泛型类型参数既不是协变类型也不是逆变类型,只能使用指定的固定类型
    6. 泛型与反射:
      • typeof可以作用于开放类型和封闭类型,
        Console.WriteLine(typeof(List<>));
        Console.WriteLine(typeof(List<int>));
        Console.WriteLine(typeof(Dictionary<,>));
        image
      • Type类中与泛型有关的重要的方法:
        • GetMethod:对于泛型类只能返回泛型类型方法定义,不能返回一个已构造的方法,只有已构造的类型方法才可以调用
          Type type=typeof(Snippet);
          MethodInfo definition=type.GetMethod("PrintTypeParameter")//PrintTypeParameter是静态泛型方法
          MethodInfo constructed=definition.MakeGenericMethod(typeof(string))//获取封闭方法
          constructed.Invoke(null,null)
        • GetGenericTypeDefinition:作用于已构造的类型,获取它的泛型类型定义
        • MakeGenericType:用于泛型类型定义,返回一个已构造类型
          Type list = typeof(List<>);
          Type closeList=list.MakeGenericType(typeof(string));
          Type openList = closeList.GetGenericTypeDefinition();
          
           Console.WriteLine(closeList);           
           Console.WriteLine(openList);
          image
    7. C#4.0能够使用out修饰符来指定类型参数的协变性,使用in修饰类型参数的逆变性
    8. CLR中可变性要注意的问题:
      • 在 .NET Framework 4中,可变性类型参数仅限于泛型接口和泛型委托类型,泛型类的类型参数不支持可变性。
      • 泛型接口或泛型委托类型可以同时具有协变和逆变类型参数。
      • 可变性仅适用于引用类型;如果为 可变性类型参数指定值类型,则该类型参数对于生成的构造类型是不变的。
      • 可变性不适用于委托组合。 也就是说,在给定类型 Action<Derived> 和 Action<Base>的两个委托的情况下,无法将第二个委托与第一个委托结合起来,尽管结果将是类型安全的。 可变性允许将第二个委托分配给类型 Action<Derived> 的变量,但只能在这两个委托的类型完全匹配的情况下对它们进行组合。
  • 相关阅读:
    【BZOJ2067】[Poi2004]SZN
    BZOJ4675
    [bzoj3522][bzoj4543][POI2014]HOTEL
    bzoj2969矩形粉刷
    bzoj2969矩形粉刷
    1419: Red is good
    【BZOJ2698】染色
    BZOJ5084[hashit]
    [WC2014]紫荆花之恋
    齐次常系数递推关系式
  • 原文地址:https://www.cnblogs.com/phenixyu/p/4262269.html
Copyright © 2011-2022 走看看