Generic(泛型)

四、Generic Classes (泛型类)
 Generic classes encapsulate operations that are not specific to a particular data type.
 (泛型类封装了不针对特定数据类型的操作)

 (1)Non-generic, in other words, concrete, classes can inherit from closed constructed base classes,
  but not from open constructed classes or from type parameters because there is no way at run time
  for client code to supply the type argument required to instantiate the base class.
  (非泛型,也就是说具体类能继承自闭合接口的泛型基类,但是不能从开放构造的泛型类或者从类型参数进行继承,
  这是因为客户端代码在运行时,无法提供实例化基类所需的类型参数)

  //No error(继承自闭合的泛型基类)
  class Node1 : BaseNodeGeneric<int> { }
  
  //Generates an error(继承开放的泛型基类时会有错误产生)
  //class Node2 : BaseNodeGeneric<T> {}

  //Generates an error(继承自类型参数会报错)
  //class Node3 : T {}

 (2)Generic classes that inherit from open constructed types must supply type arguments
  for any base class type parameters that are not shared by the inheriting class,
  as demonstrated in the following code:
  (继承自开放构造类型的泛型类,必须为基类的每个类型参数提供类型参数,因为这些类型参数是不会被
  继承类共享的,就像下面代码演示的那样:)

  class BaseNodeMultiple<T, U> { } (泛型类)

  //No error(子类提供了基类所需的类型参数T)
  class Node4<T> : BaseNodeMultiple<T, int> { }

  //No error(子类提供了基类所需的类型参数T,U)
  class Node5<T, U> : BaseNodeMultiple<T, U> { }

  //Generates an error(子类没有提供基类所需的类型参数U)
  //class Node6<T> : BaseNodeMultiple<T, U> {}

 (3)Generic classes that inherit from open constructed types
  must specify constraints that are a superset of, or imply,
  the constraints on the base type:
  (继承自开发构造类型的泛型类,必须定义一个约束集,这个约束集是子类约束集的超集,或者能
  够隐含的暗示出基类的约束)

  //一个带有约束的泛型类型(Open Constructed Generic with constraints)
  class NodeItem<T> where T : System.IComparable<T>, new() { }

  //继承的约束要能够包含基类的约束,或者至少要和基类的约束相同。
  class SpecialNodeItem<T> : NodeItem<T> where T : System.IComparable<T>, new() { }

 (4)Generic types can use multiple type parameters and constraints, as follows:
  (泛型类可以使用多个类型参数和约束,如下所示:)

  //下面泛型类有3个类型参数K,V,U,提供了两个类型参数约束where U,where V
  class SuperKeyType<K, V, U>
    where U : System.IComparable<U>
    where V : new()
  { }

 (5)Open constructed and closed constructed types can be used as method parameters:
     (开放构造和闭合构造类型的泛型类型能被用作方法的参数)

  //开放构造泛型类作为方法参数类型
  void Swap<T>(List<T> list1, List<T> list2)
  {
      //code to swap items
  }

  //闭合构造泛型类型作为方法参数类型描述
  void Swap(List<int> list1, List<int> list2)
  {
   //code to swap items
  }
五、Generic Interfaces (泛型接口)
 The preference for generic classes is to use generic interfaces
 When an interface is specified as a constraint on a type parameter,
 only types that implement the interface can be used.

 (1)Multiple interfaces can be specified as constraints on a single type, as follows:
  class Stack<T> where T : System.IComparable<T>, IEnumerable<T>
  {
  }

 (2)An interface can define more than one type parameter, as follows:
  interface IDictionary<K, V>
  {
  }

 (3)The rules of inheritance that apply to classes also apply to interfaces:
  interface IMonth<T> { }

  interface IJanuary     : IMonth<int> { }  //No error
  interface IFebruary<T> : IMonth<int> { }  //No error
  interface IMarch<T>    : IMonth<T> { }    //No error
  //interface IApril<T>  : IMonth<T, U> {}  //Error

 (4)Concrete classes can implement closed constructed interfaces, as follows:
  interface IBaseInterface<T> { }

  class SampleClass : IBaseInterface<string> { }

 (5)Generic classes can implement generic interfaces or closed constructed interfaces
  as long as the class parameter list supplies all arguments required by the interface, as follows:
  interface IBaseInterface1<T> { }
  interface IBaseInterface2<T, U> { }

  class SampleClass1<T> : IBaseInterface1<T> { }          //No error
  class SampleClass2<T> : IBaseInterface2<T, string> { }  //No error

六、Generic Methods (泛型方法)
 A generic method is a method that is declared with type parameters, as follows:
 static void Swap<T>(ref T lhs, ref T rhs)
 {
  T temp;
  temp = lhs;
  lhs = rhs;
  rhs = temp;
 }

 The following code example shows one way to call the method by using int for the type argument:
 public static void TestSwap()
 {
  int a = 1;
  int b = 2;

     Swap<int>(ref a, ref b);
  System.Console.WriteLine(a + " " + b);
 }

 You can also omit the type argument and the compiler will infer it. The following call to Swap is equivalent to the previous call:
 Swap(ref a, ref b);

 The same rules for type inference apply to static methods and instance methods.
 The compiler can infer the type parameters based on the method arguments you pass in;
 it cannot infer the type parameters only from a constraint or return value.
 Therefore type inference does not work with methods that have no parameters.
 Type inference occurs at compile time before the compiler tries to resolve overloaded method signatures.
 The compiler applies type inference logic to all generic methods that share the same name.
 In the overload resolution step, the compiler includes only those generic methods on which type inference succeeded.

 Within a generic class, non-generic methods can access the class-level type parameters, as follows:
 class SampleClass<T>
 {
  void Swap(ref T lhs, ref T rhs) { }
 }

 If you define a generic method that takes the same type parameters as the containing class,
 the compiler generates warning CS0693 because within the method scope,
 the argument supplied for the inner T hides the argument supplied for the outer T.
 If you require the flexibility of calling a generic class method with type arguments
 other than the ones provided when the class was instantiated,
 consider providing another identifier for the type parameter of the method,
 as shown in GenericList2<T> in the following example.

 class GenericList<T>
 {
  // CS0693
  void SampleMethod<T>() { }
 }

 class GenericList2<T>
 {
  //No warning
  void SampleMethod<U>() { }
 }

 Use constraints to enable more specialized operations on type parameters in methods.
 This version of Swap<T>, now named SwapIfGreater<T>,
 can only be used with type arguments that implement IComparable<T>.

 void SwapIfGreater<T>(ref T lhs, ref T rhs) where T : System.IComparable<T>
 {
  T temp;
  if (lhs.CompareTo(rhs) > 0)
  {
   temp = lhs;
   lhs = rhs;
   rhs = temp;
  }
 }

 Generic methods can be overloaded on several type parameters.
 For example, the following methods can all be located in the same class:
 void DoWork() { }
 void DoWork<T>() { }
 void DoWork<T, U>() { }

七、Generics and Arrays (泛型和数组)
 This technique is primarily useful for reading data in collections.

八、Generics in the Run Time (运行时泛型)

 


http://msdn.microsoft.com/zh-cn/library/vstudio/d5x73970.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值