I have seen several articles about covariance and inversion, but I always feel that I am not written clearly enough. The important thing about this article is to express the views you want to express. This process should be to digest the complex things and simplify them and make them clear, rather than to be mysterious and do the opposite. Let's get back to the point.
Let’s first look at a paragraph of the original MSDN text to define covariance, inversion and variants:
A generic interface or delegate is called variant if its generic parameters are declared covariant or contravariant. Both C# and Visual Basic enable you to create your own variant interfaces and delegates.
If the generic interface or delegate's generic parameters are declared as covariant or inverter, the generic interface or delegate is called a "variant". Both C# and Visual Basic allow you to create your own variant interfaces and delegates.
Common explanation:
Variation definition: a generic interface or delegate with covariant or inverter parameters. That is to say, covariance and inversion focus mainly on generic interfaces or delegates.
Then what are covariance and inversion?
Let's first look at the following example from MSDN:
1 // Covariation
2 IEnumerable<string>strings = new List<string>();
3 IEnumerable<object> objects = strings;
Have you seen an interface type declared as IEnumerable<string> is assigned to a lower level IEnumerable<object>.
Yes, this is covariance. Let’s take a look at another example:
class Base { public static void PrintBases(IEnumerable<Base> bases) { foreach(Base b in bases) { (b); } } } class Derived : Base { public static void Main() { List<Derived> dlist = new List<Derived>(); (dlist);//Because the IEnumerable<T> interface is covariant, PrintBases(IEnumerable<Base> bases) //A more concrete IEnumerable<Derived> can be received as its parameter. IEnumerable<Base> bIEnum = dlist; } }
The following is a definition of covariance:
Covariance: Make a covariance parameterGeneric interfaces (or delegates) can receive more refined types, and the specific generic interfaces (or delegates) can be regarded asAn extension of polymorphism in OO.
// Inversion// Assume that the following method is in the class: // static void SetObject(object o) { } Action<object> actObject = SetObject; Action<string> actString = actObject; //In the future, you must use more refined type string in the actString, and you can no longer use object!string strHello(“Hello”); actString(strHello);
Have you seen it? A type declared as Action<object> is assigned to an Action<string>. As we all know, Action<T> receives parameters and does not return values, so the object and string are their parameters. This process is actually the constraints of the parameters are stronger, which means that the parameter types are more refined. Let's define the inverter below:
Inverter:Let a covariate parameterGeneric interfaces (or delegates) can receive coarse granular generic interfaces or delegates as parameters. This process is actually a process of more refined parameter types.
Summary of one sentence: Covariance allows a coarse-grained interface (or delegate) to receive a more specific interface (or delegate) as a parameter (or return value); inversion makes the parameter type (or return value) of an interface (or delegate) more concrete, that is, the parameter type is stronger and more clear.
Typically, a covariant type parameter can be used as a return type for the delegate, while an inverter type parameter can be used as a parameter type. For interfaces, the covariant type parameter can be used as the return type of the interface's method, while the inverter type parameter can be used as the parameter type of the interface's method.
The above is the entire content of this article. I hope that the content of this article has certain reference value for your study or work. Thank you for your support. If you want to know more about it, please see the following links