I found an explanation What is a covariant return type? but I am no smart to understand it all.
I think Covariant return type theoritically is the type returned by a function that has the same signature with a built-in base class function whose return type is different.
class Base{
TypeX func( int i ){return typex;} // builtin function
};
class Derived:Base{
TypeY func(int i){return typey;}
}
Is my understanding of this so-called covariant return type correct ? [the term really confuses me.]
This would be an example of covariant return types:
class Food {}
class Fruit : Food {}
class FoodEater
{
public virtual Food GetFavouriteFood() { ... }
}
class FruitEater : FoodEater
{
public override Fruit GetFavouriteFood() { ... }
}
In languages that support return type covariance, this would be legal. That is a method that returns a Food can be overridden by a method that returns a Fruit, because Fruit is a kind of Food. It is called "covariance" because the "variance" is in the same direction:
A Fruit may be used as a Food, therefore:
A Fruit-returning-method may be used as a Food-returning-method
See how the variance is in the same direction?
Contrast that with parameter type contravariance:
class Food {}
class Fruit : Food {}
class Apple : Fruit {}
class Orange : Fruit {}
class Cake : Food {}
class FruitComparer
{
public virtual bool Compare(Fruit f1, Fruit f2) { ... }
}
class FoodComparer : FruitComparer
{
public override bool Compare(Food f1, Food f2) { ... }
}
A FruitComparer can compare Apples to Oranges. A FoodComparer can also compare Apples to Oranges, but can compare even more -- it can compare Apples to Cakes, or Cakes to Oranges, or whatever.
In languages that support parameter type contravariance, this is legal. See how the variance directions are now reversed:
A Fruit may be used as a Food, therefore
A Food-taking-method may be used as a Fruit-taking-method
Now the relationship has gone backwards, so it is contravariant.
C# supports neither kind of method variance for virtual overloading. Virtual method overrides must match exactly. However, C# does support both kinds of method variance for method group to delegate conversions, and for generic delegate type conversions.
Unlike java, covariant return types are not supported in C#. I believe this is due to the implementation of C# properties, if covariant return types were allowed, the following would be possible:
class TypeX { }
class TypeY : TypeX { }
class Base
{
public virtual TypeX Prop { get; set; }
}
class Derived : Base
{
public override TypeY Prop { get; set; }
}
Derived derived = new Derived();
derived.Prop = new TypeY(); // Valid
Base @base = derived;
@base.Prop = new TypeX(); // Invalid - As this would be using the derived property which should be of TypeY
See Eric Lippert's answer for more information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With