Covariance (covariant), Contravariance (inverter) and Invariance (unchanged)

On the relationship between the type and subtype, with regard to the type of conversion, the decision is to be rewritten or reloaded.

Only for generic interface or delegate.

covariant out, can be used a greater extent subclass derived supertype alternative parameters can only be used for the return value.

in an inverter, can be used more derived alternative smaller parent subtype parameters, the input parameters for the method only.

When the parameter is the time out, then it returns the actual target requires at least a parent class or subclass of T based.
When is in the time parameters: he can target argument T, T can pass the parent class object arguments inside.

Assignment compatibility
before this case to understand the "assignment compatibility" is nothing more than a derived class object can be assigned to the "base class object", not vice versa. This understanding of the concept after a period of time may be easily confused, in fact, just to understand the security access is not easy to forget. Derived class is inherited from the base class, has its own private things,

The derived class object is assigned to a base class object Dog Animal, Animal target animals access to property in the Dog object can have access to;
but if you turn, the object is assigned to the Animal Dog object if, Dog object has access to memory it is much more than the animal object, such as a dog's nose is very spiritual, animals may not be very spiritual, this time with a visit this property dogleg dog object, assign the result to the dog object of this dogleg animal object has no property, perhaps to visit is irrelevant, maybe a bunch of gibberish, this time if it belongs to the people of heap memory Rabbit object, you want to let other Emaoagou how Rabbit's, they are not objects.
So in terms of security, in order not to become a dogleg rabbit leg, in order to defend the rabbit home (memory) security, the base class can not be assigned to the derived class.

Covariant
first reading section on the covariant code:

class Animal { public int Legs = 4;}
class Dog : Animal { }
delegate T Factory ( );

class Program
{
static Dog MakeDog()
{
return new Dog();
}
static void main()
{
Factory dogMaker = MakeDog;
Factory animalMaker = dogMaker;
Console.WriteLine(animalMaker().Legs.ToString());
}
}

First glance dogMaker assigned to animalMaker derived class is not assigned to the base class it? What's the fuss about, in fact, the principal contradiction here is not that assignment compatibility, but rather, Factory And Factory It is not the same type, dogMaker and animalMaker not the Dog and Animal class.
Here dogMaker agent function returns Dog object, animalMaker Animal object proxy function returns, the return value from the assignment for compatibility, animalMaker = dogMaker entirely feasible, only that they belong contradiction Factory And Factory The two delegate types, between two flat stages how into each other, just like humans and dogs can not be transformed into each other, like (people and dogs belong to animals, but people! = (Person) dog.
At this time it is played out keyword the critical role of the, out keyword tells the compiler that this brother with the parameters I just used to output, you do not control Factory And Factory Maybe the guy as long as I took the little brother in line with the assignment compatibility on the line.

逆变
class Animall { public int NumberOfLegs = 4; }
class Dog : Animal{}
class Program
{
delegate void Action (T a);
static void ActionAnimal(Animal a) { Console.WriteLine(a.NumberOfLegs); }
static void main()
{
Action1 act1 = ActOnAnimal;
Action1 dog1 = act1;
dog1(new Dog());
}
}

From static void ActionAnimal (Animal a) { Console.WriteLine (a.NumberOfLegs);} This code point of view, just the opposite and covariant, covariant emphasize only used as an output parameter, and here it is forced by Animal a in Console.WriteLine (a.NumberOfLegs) ;, where only an input.
So here in keywords will play a key role, and it tells the compiler, I took the little brother only used as an input parameter, you do not control act1 and dog1 is not the same type, you just function of the two principal-agent input parameters are consistent with the assignment compatibility on the line.

Summary
online this sentence, I do not think of:

The transition from the subclass is the parent class direction covariant covariant return type for a keyword out
shift direction indicated by the subclass is the parent class parameter type inverter using an inverter method for keywords in

You can see from the above two pieces of code, either covariant or inverter, by its very nature must comply with the class assignment compatibility.

Only parameter covariance output parameter, dogMaker returns Dog, assigned to the Animal animalMaker impending return, i.e., the base class to the derived class assignment, assignment compatibility compliance;
Factory's dogMaker = MakeDog;
Factory animalMaker = dogMaker;
Console.WriteLine(animalMaker().Legs.ToString());

Inverter parameter only input parameter, dog1 (new Dog ()) = act1 (new Dog ()) = ActOnAnimal (new Dog ()); where a new Dog is converted into Animal, also consistent assignment compatibility;
the Action1 act1 = ActOnAnimal;
Action1 dog1 = act1;
dog1(new Dog());

Also think about it, can not do input and output parameters at the same time it? Look at the code below:

class Animal { public int Legs = 4;}
class Dog : Animal { }
delegate T Factory (T t );

class Program
{
static Dog MakeDog(Dog dog)
{
Console.WriteLine($"{dog.legs}");
return new Dog();
}
static Animal MakeAnimal(Animal animal)
{
Console.WriteLine($"{animal.legs}");
return new Animal();
}
static void main()
{
Factory dogMaker = MakeDog;
Factory animalMaker = dogMaker; // Can not Factory Implicitly converted to Type Factory Types of

Factory A = Make animal;
Factory b = a; // can not Factory Implicitly converted to Type Factory 类型
Console.WriteLine(animalMaker().Legs.ToString());
}
}

This code will not compile, after this modification, Factory commissioned by the generic parameter t, not only do they make the return value of the input value, then no matter which side is assigned to which side will face the base class object assigned to the derived class embarrassment object, there is not a place in the incoming parameters, return values is what has happened in there. Thus in order to understand the why out (only output parameters) and in (only input parameters) these two keywords, because you want to be able to convert, you have to comply with the assignment compatibility.
Of course, if you do not give these two keywords, but exactly in line with the assignment compatibility it? I think the compiler is not so smart, you did not tell it, it can not be judged.

But here I am still exists a doubt, even with out and in defining the parameters, but the Factory And Factory Still not the same type ah, the pre-existing problem.

Guess you like

Origin www.cnblogs.com/wesson2019-blog/p/12126441.html