C #4.0 generic covariant, in-depth analysis of inverters

Source: Internet
Author: User

C #4.0 has a new feature: covariant and inverter. Many people may not often use it in the development process, but it is certainly advantageous to have a deep understanding of them. The covariant and inverter are reflected in generic interfaces and delegation, that is, the declaration of generic parameters. They can be declared as covariant or inverter. What? Can generic parameters be declared? If a parameter Declaration is available, the generic interface or delegate is called a "Variant ". List <automobile> A group of cars = new List <automobile> (); List <automobile> A group of cars = a group of cars; obviously, the above Code will report an error, although a car inherits from a car, it can be converted from a hermit to a car, but the List <car> does not inherit from the List <car>, so the above conversion won't work. IEnumerable <automobile> A group of cars = new List <automobile> (); IEnumerable <automobile> A group of cars = a group of cars; however, this is acceptable. So what is the difference between the IEnumerable interface? Let's look at the compiler prompt: we can see that for generic parameters, a "out" keyword is used as a declaration. It seems that the key is that this is working. "Covariant" refers to a type with a greater degree of derivation than the original specified derivative type. "Invert" refers to a type that can be derived to a smaller extent. Inverter, which is opposite to conventional changes. The two keywords are "out" and "in. However, it can only be used for interfaces and delegation. When it is declared as "out", it indicates that it is used for return and can only be returned as a result. It cannot be changed in the middle. When declared as "in", it indicates that it is used for input. It can only be input as a parameter and cannot be returned. Return to the example above, because the "IEnumerable" interface declares the out, it means that the T parameter can only be returned and will not be modified in the middle, IEnumerable <car> A group of cars = a group of cars. This forced conversion is legal. In IL, it is actually forced conversion. IEnumerable is self-contained in NET, and other interfaces and delegation are as follows: Copy code interface: IQueryable <out T> IEnumerator <out T> IGrouping <out TKey, out TElement> IComparer <in T> IEqualityComparer <in T> IComparable <in T> delegate: System. action <in T> System. func <Out Tresult> Predicate <in T> Comparison <in T> Converter <in TInput, out TOutput>, we can also use covariant and inverter when defining generic interfaces. Let's look at an example to demonstrate the feature interface of covariant <out T> {T attribute {get; set ;}} I define an interface that has the get and set accessors attributes. However, an error is reported during compilation, prompting that the variant is invalid: The type parameter "T" must be fixed for the "test. Interface <T>. Attribute. "T" is a covariant. Because I declared T as a covariant, T can only be returned and cannot be modified. Therefore, if the "set" accessors are removed, T can be compiled and passed. Similarly, if I declare a method void method (T t) in the "interface", it will also report an error. T is declared as a covariant, "method (T t). Copy the code class Program {static void Main (string [] args) {interface <automobile> A group of cars = new class <automobile> (); interface <car> A group of cars = a group of cars;} interface <out T> {T attribute {get ;}} class <T>: the code above the copy operation <T >{public T property {get {return default (T) ;}} can be compiled, because the generic interface "interface" declares the covariant, the "interface <car> A group of cars = a group of cars;" can be forcibly converted. Let's see, we can also achieve our own goals. What if I change the above Code from "out" to "in? Obviously not, because the Declaration "in" specifies that T cannot be returned and compilation fails. However, the following code is correct: copy the code interface <in T> {void method (T t);} class <T>: interface <T> {public void method (T t) {}} copy the code Declaration "in" and it cannot be returned, but can be changed. Next Look: copy the code static void Main (string [] args) {interface <car> A group of cars = new type <car> (); interface <automobile> A group of cars = a group of cars;} copy the code. How can this be done? "car" is the parent class, and "car" is a subclass, how can we convert a car to a normal one? In fact, "car" or "car" are only generic parameters here, not the conversion between them. This basic concept must be understood and should not be bypassed. This is the inverter. Because the "interface" declares the "in" keyword and is declared as an inverter, allowing the parameter to accept a relatively "weak" type is actually to make the type of a parameter more specific, A more explicit process.

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.