Covariant generic type (covariant) and an inverter

Official website: http: //msdn.microsoft.com/zh-cn/library/dd799517.aspx

Original link: http: //book.51cto.com/art/201112/308570.htm

 Reference link: http: //www.cnblogs.com/yukaizhao/archive/2011/10/27/xiebian-nibian.html

 

1.3.4 covariant generic type (covariant) and an inverter (contravariant)

In previous versions of the .NET 4.0, the generic type is not supported covariant and contravariant, but delegate type parameter is covariant and contravariant support. Covariance and what is it? In programming languages, "covariant" refers to the type of use of a greater extent compared to the original derivation of the derived type specified; the "inverter" refers to the extent possible to use less-derived type.

The following code illustrates the delegate type well covariant. Animals Given a class, a subclass derived therefrom Dogs, then when defining a delegate that returns Animals. Users can also return a commission to the delegate assignment Dogs called covariant codes see 1.4.

1.4 Code commissioned covariant

  1. class Program  
  2.     {  
  3.         public delegate Animals HandlerMethod (); // return commission Animals  
  4.         public static Animals FirstHandler () // method to achieve returns Animals  
  5.         {  
  6.             Console.WriteLine ( "return Animals delegate");  
  7.             return null;  
  8.         }  
  9.         public static Dogs Secondhandler () // method to achieve returns Dogs  
  10.         {  
  11.             Console.WriteLine ( "return Dogs delegate");  
  12.             return null;  
  13.         }  
  14.         static void Main(string[] args)  
  15.         {  
  16.             HandlerMethod  handler1  =  FirstHandler ; // standard commission  
  17.             HandlerMethod  handler2 is  =  Secondhandler ; // delegate covariant  
  18.         }  
  19.     }  
  20.     // define a class of Animals  
  21.     public class Animals  
  22.     {  
  23.         public string  Location { get; set; }  
  24.     }  
  25.     // define a class derived from Animals of Dogs  
  26.     public class Dogs : Animals  
  27.     {  
  28.         public string Cry { get; set; }  
  29.     } 

In the above code, the first defined Animals Dogs classes and class, and define a named HandlerMethod delegate, the delegate type of return value Animals. In the Main () method, Animals were assigned a value and a type of return value of the method return type Dogs. Can be seen that, since the covariant commissioned characteristics, such a return would be acceptable delegate Animals Dogs return a commission.

.NET 4.0 is introduced in / out parameters, that the generic type of covariant and inverter is achieved. For example defines a generic interface or generic delegate, the keyword may be used out, the generic type parameter is declared as covariant. Covariant type must satisfy the condition: an interface type only as the return type, the type is not used as method parameter.

You can use the keyword in the generic type parameter declared as an inverter. The inverter type only used as a type of method parameters, the interface can not be used as the return type. Type inverter can be used for generic constraints. The following example demonstrates how to use the in / out parameters to set covariant generic type and an inverter. Codes using covariant see 1.5.

1.5 generic codes covariant

  1. the ITest interface < OUT  T >                   // define a covariant interfaces support  
  2. {  
  3.     T X {get;} // Properties  
  4.     T M (); // return type of process T  
  5. }  
  6. // define a generic class that implements the interface  
  7. class TestClass<T> : ITest<T> 
  8.   where T: Base, new () // constraint is derived from T to Base, with a constructor  
  9. {  
  10.     public T X { get; set; }  
  11.     // implement generic method  
  12.     public T M()  
  13.     {  
  14.         return new T();  
  15.     }  
  16. }  
  17. // define two classes  
  18. class Base { }  
  19. class Derived : Base { }  
  20. class Program  
  21. {  
  22.     static void Main(string[] args)  
  23.     {  
  24.         ITest<Derived> _derived =   
  25.             new new  the TestClass < the Derived >  {  X-  =  new new  the Derived ()}; // initialize using object syntax initial value  
  26.         The ITest < Base > _base  =  the _derived ; // generic covariant   
  27.         Base x = _base.X;   
  28.         Base m = _base.M();  
  29.     }  

In the above code, the ITest defines a generic interface, a note used to support out parameter covariance. Then TestClass generic class implements the interface, and defines the generic constraints specified type must be derived from the T sub Base class. Main can be seen in the main form, it defines a ITest interface, and then use the generic covariant characteristics for conversion between the generic type.

And covariant contrast, the inverter converts the base class is a derived class, the following two rules generic inverter:

Constrained by the generic parameter in a keyword, property can only be used to set or delegate (method) parameters.

Generic parameter type implicit conversion goal must be a current type of "inheriting class."

For example, code that defines an interface 1.6, which is demonstrated to allow covariant, which allow the inverter.

1.6 the code inverter interface

  1. interface ITest<in T> 
  2. {  
  3.     T X  
  4.     {  
  5.         get; // get the properties do not allow the inverter  
  6.         set; // set the property allows the inverter!  
  7.     }  
  8.     T M (T o); // only allow method parameters, return value can not be applied to the method of  

In contrast to the covariance, the inverter polymorphism in line with the law, the inverter some puzzling, but the main inverter is prepared for generic delegate. Using an inverter as shown in the code 1.7.

1.7 Code commissioned inverter

  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         The Action < Base > _base  = (O) = >  Console.WriteLine (O); // define a base class Base   
  6.         The Action < the Derived > the _derived  =  _base ; // convert using covariant base class to derived class   
  7.         _derived (new Derived ()); // inverter results  
  8.     }  

The above code creates a delegate based Base class, but in a later assignment, the base class is assigned to a derived class, the inverter is formed.

Reproduced in: https: //my.oschina.net/garyun/blog/602776

Guess you like

Origin blog.csdn.net/weixin_33958366/article/details/91774071