C #4.0 covariant and invert of new features,
1. C #3.0 co-Variation and inverter before
If this is the first time you have heard of these two words, don't worry. They are actually very common. In C #4.0, the covariant and inverter [1] (Covariance and contravariance) have been further improved, mainly because of the (implicit) generic type parameter conversion in the two runtime types. To put it simply, Covariance refers to raising the type from "small" to "big", for example, upgrading from subclass to parent class; invert refers to changing from "big" to "small". The two have different conditions and uses. The following example demonstrates the support for covariant and inverter before C #3.0 [2]:
Code 1
Public class Animal {}
Public class Cat: Animal {}
Public delegate Animal AniHandler (Animal );
Public static Animal AniMethod (Animal a) {return null ;}
Public static Cat CatMethod (Object o) {return null ;}
Public static void TestCovariance ()
{
AniHandler handler1 = AniMethod;
AniHandler handler2 = CatMethod; // This is valid
}
Although the CatMethod here does not strictly satisfy the signature of the delegate AniHandler, it is legal to use it as an AniHandler. In Cat-> Animal and invert (object-> Animal) under the role of, in the delegate pointing method, the input parameter can be a large, broad type, and the returned result can be smaller, exact type (subclass) because it contains more information. Note that this is in the method, and the caller uses the method in the opposite way. When calling a method, the parameter can be a sub-class of "small, the returned value can be used as a "large" parent class. The following calls are legal:
Object o = AniMethod (new Cat ());
Haha, it sounds a little dizzy. Now I want to try to clearly express the problem. Whether it is covariant or invert, it is to make such a very reasonable fact: if the provided type information is more (rather than equal) than the required type information ), of course this is acceptable. In the example of code 1, The AniHandler delegate requires an Animal as the return value, but I return a Cat to it. Cat contains all the features of Animal, which of course is acceptable, this is the covariant. At the same time, the AniHandler needs an Animal as the parameter. In order to make the function obtain more information than required, I only need to upload an object, which of course works, this is the inverter.
2. covariant in C #4.0
Let's take a look at how a harmonious change occurs. The covariant in C #4.0 is very similar to the loose delegate in C #3.0. The new C # covariant feature is also reflected in the type parameters of the generic interface or generic delegate. Take the classic Animal and Cat as an example. After you read the code 1 above, since Cat CatMethod () can be used as Animal AniHandler, you have reason to believe that the following code is also valid in C #3.0:
Code 3
Delegate T THandler <T> ();
Static void Main (string [] args)
{
THandler <Cat> catHandler = () => new Cat ();
THandler <Animal> aniHandler = catHandler; // Covariance
}
Sorry, you are wrong. in C #3.0, the above Code cannot be compiled, and you will be notified of this error:
The times have improved, and the C #4.0 compiler now supports the above writing. You only need to add an out keyword before declaring the THandler type parameter:
Delegate T THandler <out T> ();
Using a single keyword instead of directly allowing implicit conversion is also for type security considerations. So when you write out, you should know the possible Covariance.
Inverter in 3.c #4
We continue to use the Animal and Cat examples. In VS2008, the following code cannot be compiled:
Code 5
Delegate void THandler <T> (T t );
Public static void TestContravariance ()
{
THandler <Animal> aniHandler = (ani) => {};
THandler <Cat> catHandler = aniHandler;
}
In VS2010, er, no. In fact, it is a little bit worse. If the keyword "in" is added before the type parameter T, that is, delegate void THandler <in T> (T t ); you can implement Cat-> Animal Contravariance.
4. Summary
The type conversion in C #4 is more natural because of the covariant and inversion in generic programming. However, note that the above mentioned covariant and inverter only apply to reference types, currently, only generic interfaces and delegation can be used. A t parameter can only be in or out. If you want to change the value of your delegate parameter to an inverter (as shown in code 1), you cannot do so.
In C language-> what?
-> Is a whole. It is used to point to a struct, class in C ++, and other pointers containing sub-data to obtain sub-data. In other words, if we define a struct in C and declare a pointer pointing to this struct, we need to use "->" to retrieve the data in the struct using the pointer ".
For example:
Struct Data
{
Int a, B, c;
};/* Define struct */
Struct Data * p;/* define struct pointer */
Struct Data A = {1, 2, 3};/* declare variable */
Int x;/* declare a variable x */
P = & A;/* point p to */
X = p-> a;/* indicates that the data item a in the struct pointed to by p is assigned to x */
/* Because p points to A, p-> a = A. a, that is, 1 */
For the first problem, p = p-> next; this should appear in the linked list of C language. next here should be a struct pointer of the same type as p, and its definition format should be:
Struct Data
{
Int;
Struct Data * next;
};/* Define struct */
............
Main ()
{
Struct Data * p;/* declare the pointer Variable p */
......
P = p-> next;/* assign the value in next to p */
}
The linked list pointer is a difficulty in C language, but it is also the key. It is very useful to learn it. To be careful, you must first talk about variables and pointers.
What is a variable? The so-called variables should not be simply thought that the amount will become a variable. Let's use the question of our Dean: "Is the classroom changing ?" Change, because there are different people in the classroom every day, but they do not change, because the classroom is always there, and it does not become larger or smaller. This is the variable: There is a constant address and a variable storage space. Under normal circumstances, we only see the variable in the room, that is, its content, but do not pay attention to the variable address, but the C language pointer is the address of the room. We declare that variables are equivalent to building a house to store things. We can directly watch things in the house, while declaring pointers is equivalent to getting a positioner. When a pointer points to a variable, it is to use the pointer to locate the variable. Then we can use the pointer to find the variable "tracked" and get the content in it.
What about struct? The structure is equivalent to a villa composed of several houses, and several houses are bound for use together. Suppose there are many such villas distributed in a big maze, and each villa has a house. The location information of another villa is put in it. Now you have found the first villa with the positioner and obtained what you want from it (the data part of the linked list ), then, calculate the location of the next villa into your positioner (p = p-> next), and go down to the next villa ...... If you go on like this, you will know that the information of a villa on the ground is gone (p-> next = NULL), and your trip is over. This is the process of traversing a linked list. Now you can understand the meaning of p = p-> next!
Write so much. I hope you can understand.
If you want to learn c and C ++ well, you must be familiar with linked lists and pointers!
In C language-> what?
-> Is a whole. It is used to point to a struct, class in C ++, and other pointers containing sub-data to obtain sub-data. In other words, if we define a struct in C and declare a pointer pointing to this struct, we need to use "->" to retrieve the data in the struct using the pointer ".
For example:
Struct Data
{
Int a, B, c;
};/* Define struct */
Struct Data * p;/* define struct pointer */
Struct Data A = {1, 2, 3};/* declare variable */
Int x;/* declare a variable x */
P = & A;/* point p to */
X = p-> a;/* indicates that the data item a in the struct pointed to by p is assigned to x */
/* Because p points to A, p-> a = A. a, that is, 1 */
For the first problem, p = p-> next; this should appear in the linked list of C language. next here should be a struct pointer of the same type as p, and its definition format should be:
Struct Data
{
Int;
Struct Data * next;
};/* Define struct */
............
Main ()
{
Struct Data * p;/* declare the pointer Variable p */
......
P = p-> next;/* assign the value in next to p */
}
The linked list pointer is a difficulty in C language, but it is also the key. It is very useful to learn it. To be careful, you must first talk about variables and pointers.
What is a variable? The so-called variables should not be simply thought that the amount will become a variable. Let's use the question of our Dean: "Is the classroom changing ?" Change, because there are different people in the classroom every day, but they do not change, because the classroom is always there, and it does not become larger or smaller. This is the variable: There is a constant address and a variable storage space. Under normal circumstances, we only see the variable in the room, that is, its content, but do not pay attention to the variable address, but the C language pointer is the address of the room. We declare that variables are equivalent to building a house to store things. We can directly watch things in the house, while declaring pointers is equivalent to getting a positioner. When a pointer points to a variable, it is to use the pointer to locate the variable. Then we can use the pointer to find the variable "tracked" and get the content in it.
What about struct? The structure is equivalent to a villa composed of several houses, and several houses are bound for use together. Suppose there are many such villas distributed in a big maze, and each villa has a house. The location information of another villa is put in it. Now you have found the first villa with the positioner and obtained what you want from it (the data part of the linked list ), then, calculate the location of the next villa into your positioner (p = p-> next), and go down to the next villa ...... If you go on like this, you will know that the information of a villa on the ground is gone (p-> next = NULL), and your trip is over. This is the process of traversing a linked list. Now you can understand the meaning of p = p-> next!
Write so much. I hope you can understand.
If you want to learn c and C ++ well, you must be familiar with linked lists and pointers!