Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

subtype and covariant return type

Tags:

java

c#

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.]

like image 587
user1058272 Avatar asked Mar 24 '26 22:03

user1058272


2 Answers

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.

like image 118
Eric Lippert Avatar answered Mar 26 '26 12:03

Eric Lippert


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.

like image 25
Lukazoid Avatar answered Mar 26 '26 12:03

Lukazoid



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!