[C #] talking about covariant and inverter,

Source: Internet
Author: User

[C #] talking about covariant and inverter,

Although I have read several blogs about covariant and inverter, they are all correct, but I feel that they are not clear-cut and have no key points.
So I also try to talk about covariant and inverter from my perspective.


What is covariant and inverter?

MSDN explanation:
Https://msdn.microsoft.com/zh-cn/library/dd799517.aspx

Both the covariant and the inverter are terminologies. The former refers to a type that can be derived to a lower degree (not specific) than the original specified derivative type, the latter refers to a type that can be derived more (more specific) than the original specified derivative type.
Generic Type parameters support covariant and inverter, providing greater flexibility in allocating and using generic types.

At the beginning, I could not tell whether the changes were covariant or inverter, because the MSDN explanation was more rigorous and less readable.
In fact, it is quite easy to understand these two concepts from the Chinese perspective:

"Covariant" means "coordinated transformation", "inverter" means "reverse transformation ".

Why is it possible to use a type that is less (not specific) than the original specified derivative type, however, "a type that can be used to derive a greater degree (more specific) than the original specified derivative type" is inverse. Let's look at the two lines of code:

object o = "";string s = (string) o;

String-to-object type, that is, the conversion from a derived class to a base class, can be implicitly converted, because the conversion from any type to the base class is of type security, so this transformation is considered to be coordinated.
The object type to the string type, that is, the base class to the derived class, can only be explicitly converted, because the actual type of object o is not necessarily string, forced conversion is not type-safe, therefore, this transformation is considered inverse.

Let's look at the common scenarios of covariant and inverter:

IEnumerable <object> o = new List <string> (); // covariant Action <string> s = new Action <object> (arg) => {...}); // Inverter

The Generic parameters in the above example are the coordinated and inverse changes.

 

Objects of the change and Inverter

From the definition, we can see that both the covariant and inverter are generic parameters, and

In. NET Framework 4, Variant type parameters are limited to generic interfaces and generic Delegate types.

Why interfaces and delegation? First, let's look at the Declaration of IEnumerable <T> and Action <T>:

public interface IEnumerable<out T> : IEnumerable{    new IEnumerator<T> GetEnumerator();}public delegate void Action<in T>(T obj);

The out keyword in IEnumerable provides the capability of covariant for generic parameters, And the in keyword in Action provides the capability of inversion for generic parameters.
Here, the out and in are relative to who's in and out? It is not relative to the interface and delegate, but to the method body!
See their implementation:

class MyEnumerable<T> : IEnumerable<T>{    public IEnumerator<T> GetEnumerator()    {        yield return default(T);    }    IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }}Action<string> myAction = new Action<object>(    (o) =>    {        Console.WriteLine(o.ToString());    });

Does this show how generic parameters are imported and output?
What is the relationship between interfaces and delegation and methods? What is the relationship between them? The following is my understanding:

The interface type defines a set of method signatures, and the delegate type defines a method structure (method signature division method name ).
Both the interface instance and the delegate instance contain a set of method entries.

To sum up, the objects used by the covariant and inverter are generic parameters in the method body.

 

Why allow covariant and Inverter

Both the covariant and the inverter convert types. Once the type conversion is involved, you must consider the type security issue.
The reason why covariant and inverter work properly is that all types involved here are type-Safe!
Look back at the first four lines of code:

1 object o1 = ""; // type security 2 string s1 = (string) o1; // non-type security 3 IEnumerable <object> o2 = new List <string> (); // covariant 4 Action <string> s2 = new Action <object> (arg) => {...}); // Inverter

Obviously, the objects in the second row to the string are non-type safe. Why is the objects in the fourth row to the string type safe?
Based on the example of the previous method body, let's look at this Code:

1 Action<List<int>> myAction = new Action<IList<int>>(2     (list) =>3     {4         Console.WriteLine(list.Count);5     });6 myAction(new List<int> {1, 2, 3});

The first line seems to be converting IList into List, but it is actually like this:
The real parameter passed in Row 6 is a List, which enters the method body. The List is converted to IList, and the Count attribute of IList is used.
Therefore, when passing parameters, the conversion from the derived class to the base class actually occurs, that is, the type is safe.

The covariant from List <string> to IEnumerable <object> is similar:

 1 IEnumerable<Delegate> myEnumerable = new List<Action> 2 { 3     new Action(()=>Console.WriteLine(1)), 4     new Action(()=>Console.WriteLine(2)), 5     new Action(()=>Console.WriteLine(3)), 6 }; 7 foreach (Delegate dlgt in myEnumerable) 8 { 9     dlgt.DynamicInvoke();10 }

The real parameter is three actions, and the Delegate DynamicInvoke method is called, which is completely type-safe conversion.

 

The last thing I want to talk about is that all the hard-coded knowledge is far less reliable than fully understood knowledge.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.