Please read this article before reading:
Http://www.cnblogs.com/CLR010/p/3274310.html
For covariance and contravariance, always remember the three principles, and remember that all three points are clear!
1. Regardless of covariance or contravariance, the type transformation that is finally followed is = = = "Subclass converted to parent class, such as string=" object; that is, the derived class is transformed into a derived class;
2. Covariant modifiers are out, covariant, covariant-modified type parameters can only be used as return values! cannot be used for input parameters, compile not past;
3. The inverse modifier is in, the inverse of the modified type parameter can only be used as input parameters! cannot be used to return a value, compilation does not pass;
/// <summary> /// /// </summary> /// <typeparam name= "TN" >contravariant type Parameters</typeparam> /// <typeparam name= "TX" >Covariant type parameters</typeparam> Interfaceidemo<inchTn outTx> { /// <summary> ///covariant, out modifier type parameter y can only be used for return values! /// </summary> /// <returns></returns>TX Xb (); /// <summary> ///contravariant, in modified type parameter T can only be used for input parameters! /// </summary> /// <param name= "param" ></param> voidNb (TN param); /// <summary> ///examples of combinations/// </summary> /// <param name= "param" ></param> /// <returns></returns>TX Get (TN param); } classa:idemo<Object,string> { Public stringXb () {Throw Newnotimplementedexception (); } Public voidNb (Objectparam) { Throw Newnotimplementedexception (); } Public stringGet (Objectparam) { Throw Newnotimplementedexception (); } } classb:idemo<string,Object> { Public ObjectXb () {Throw Newnotimplementedexception (); } Public voidNb (stringparam) { Throw Newnotimplementedexception (); } Public ObjectGet (stringparam) { Throw Newnotimplementedexception (); } }
Static voidMain () {//parameter types are exactly the same and can be compiled byidemo<string,Object> correctdemo=NewB (); //Notice how CorrectDemo2 is declaredidemo<string,Object> correctdemo2=NewA (); //the right way Objectresult= Correctdemo2.get ("111"); //wrong parameter type//Correctdemo2.get (New Object ()); //inability to covariant and invert//idemo<object, string> wrongdemo = new B ();}
Analysis
1. Through idemo<string, Object> declares CorrectDemo2, so the signature of the CorrectDemo2 get method is an object get (string p); Note: According to principle 2, 3,string is the inverse parameter, can only do input parameters, object is covariant parameter, can only do return value
2. According to the definition of Class A, we conclude that the signature of the Get method of Class A is string get (object param)
The 3.correctdemo2 reference points to an instance of Class A! So when CorrectDemo2 executes, the actual method of execution is actually the Jiangzi string get (object param), which is the get method of a
4. But the arguments passed when we called the CorrectDemo2 get method are of type String! The Get method of a can accept parameters of type Object! OK our principle 1 appearances (look back), string= "object follows the principle that the derived class is converted to a derived class; So the Get method can execute the
5. Then continue, the result of a Get method execution is a string type! And CorrectDemo2 is actually accepting the result of an object type; OK our principle 1 again, string= "object follows the principle of being derived to a derived class; So the Get method returns the result successfully ~
6. The fourth step is the process of inversion, the fifth step is the process of co-change;
This is the information that CorrectDemo2 displays when it is called, requires a parameter of type string, returns the result of object;
Then we use the Immediate window to see CorrectDemo2 when we debug.
The original is a type, except that it is called when it is called by the method signature of the interface.
And then look at the CorrectDemo2 method.
is actually the argument of the object, the result of the string;
The whole process of execution is jiangzi;
Wide picture, can right-click, open in New window
7. The so-called covariant can be understood as a subclass conversion to a base class, the inverse of the transformation of the base class into a subclass; because we are assigning a to the Idemo, it seems that there is both covariance and inversion, in fact, only "covariant"; for example, the conversion of a type is from a subclass to a parent class! The subclass is not allowed to declare the parent class because it is object-oriented;
To implement contravariance and covariance, the in and out keywords must be implemented;
examples, such as
/// <summary> /// /// </summary> /// <typeparam name= "T" >Both the return value type and the input parameter type</typeparam> Internal InterfaceIcommon<t> { /// <summary> ///Both the return value type and the input parameter type/// </summary> /// <param name= "T" ></param> /// <returns></returns>T Geta (T T); } classc:icommon<string> { /// <summary> ///The return value is string, and the input parameter is also a string/// </summary> /// <param name= "T" ></param> /// <returns></returns> Public stringGeta (stringt) {Throw Newnotimplementedexception (); } } classd:icommon<Object> { /// <summary> ///The return value is object, and the input parameter is also an object/// </summary> /// <param name= "T" ></param> /// <returns></returns> Public ObjectGeta (Objectt) {Throw Newnotimplementedexception (); } }
Static void Main () { // cannot compile icommon<Objectnew C (); // cannot compile icommon<stringnew D ();}
Above, the IC has the covariant condition, cannot satisfy the inverse change, because the type parameter even if the return value is the input parameter, the Geta input parameter and the return value of C are string, and the IC requires the return value and the input parameter are object, return value string= "Object covariant condition is established, But input parameter object= "string is a deviation from the principle" subclass to Parent class "
The ID has the condition of inversion, cannot satisfy the covariance;
Personal understanding, is purely to stimulate, improper place please correct me;
The experience of C # covariance and inversion