A detailed description of contravariance and covariance in C #

Source: Internet
Author: User
This article is mainly for you to introduce in detail the C # inverter and covariance related data, with a certain reference value, interested in small partners can refer to

More delegate delegate and lambda expressions are used in this article, and if you're not familiar with them, check out my article delegate and anonymous delegates, anonymous delegates and lambda expressions to help you build a complete knowledge system.

In the process of C # from birth to development and growth, new knowledge points are constantly introduced. Contravariance and covariance are not original C #, but are subsequently introduced. In Java there are also contravariance and covariance, follow-up I will also write a Java inverter covariance article, interested friends can pay attention to.

Inversion and co-change, sounds very abstract, advanced, in fact, very simple. Look at the following code:


Class Person {} class Student:person {} class Teacher:person {}  class program {  static void Main (string[] ar GS)  {   list<person> plist = new list<person> ();   plist = new list<student> ();   plist = new list<teacher> ();}}

In the above code, plist = new list<student> (), plist = new list<teacher> () produces a compilation error. Although the person is the parent of Student/teacher, but the list<person> type is not the parent class of the list<student/teacher> type, the above assignment statement type conversion failed incorrectly.

As such, the assignment is not allowed before C # 4.0, and type safety is the primary factor as to why it is not allowed. Look at the following sample code:


list<person> plist = new list<student> ();p List. ADD (New Person ());p list. ADD (New Student ());p list. ADD (New Teacher ());

The following example assumes that list<person> plist = new List<student> () allows assignment, that plist although the type is list<person> set, the actual point is list< Student> collection. Plist. Add (new Person ()), the addition operation is actually called List<student>. ADD (). The person type cannot be safely converted to student, so the set definition does not make sense, so the assumptions above are not true.

But the situation changed after C # 4.0, not " something impossible ", but a new adjustment to the flexibility of the application. The same program as in C # 4.0 is still not allowed, but there are exceptions. Starting with C # 4.0, in generic delegates, generic interfaces, special cases are allowed to occur (essentially, no special changes have occurred, as explained later). The following example:


delegate void Work<t> (T item); Class person{public  string Name {get; set;}} Class student:person{public  string like {get; set;}} Class teacher:person{Public  string Teach {get; set;}} Class program{  static void Main (string[] args)  {   work<person> worker = (p) + = {Console.WriteLine (P . Name); }; ;   Work<student> Student_worker = (s) + = {Console.WriteLine (s.like);};   Student_worker = worker; Compile error here  }}

According to the previous theoretical support, Student_worker = worker, the error is easy to understand. But the purpose of our program here is to let Woker act as work<student> function, and later calls Student_worker (s) actually call Woker (s). In order to meet our needs, the process needs to be handled in 2 ways:

1, because in the call Student_worker (s), the actual execution is Woker (s), so the type of s variable is required to successfully convert to Woker required parameter type.

2. You need to tell the compiler that it allows you to assign an object of type work<person> to a variable of type work<student>.

Condition 1 when Student_worker () is called, the compiler prompts the requirement that the parameter must be an student type object that can be successfully converted to the person type object.

Condition 2 requires an adjustment to the woke delegate definition, which is adjusted as follows:


delegate void Workin<in t> (T item);

Change the name of the delegate to Workin is for but do not modify before and after the delegate, the key point is <in t>. By adding the In keyword, label the generic delegate's type parameter T, which is used only as a parameter to the delegate method. At this point the program above is compiled and executed successfully.


delegate void Workin<in t> (T Item), class program {  static void Main (string[] args)  {   Workin<person > Woker = (p) = = {Console.WriteLine (p.name);};   workin<student> student_worker = Woker;   Student_worker (new Student () {name= "Tom", like= "C #"});  }

For the requirement that the type parameter be a subtype, the value of the assignment type argument to the parent type is called the inverse of the variable. Contravariant in C # requires the type parameter of the generic in the in dimension. Contravariance is called contravariance, but it is only the form of a parent object that is assigned to a subclass variable, which is essentially the type conversion of the parameter when the method is called. Student s = new Person (), which is not possible, this is not contravariant is wrong.

The above code as you can convert to the following form, then you can forget the inversion, the essence is more important than the phenomenon

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.