Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Covariance with C# and Interfaces

Tags:

c#

covariance

I'm not clear on the concept of Covariance in C# when it comes to interfaces. Strictly based on my example below, is this an example of Covariance, please describe why or why not.

class Program
{
    static void Main()
    {
        ICarInterface car = new Car();
    }
}

interface ICarInterface
{
    void Start();
}

class Car : ICarInterface
{
    public void Start()
    {

    }
}
like image 532
Exocomp Avatar asked Jun 19 '16 12:06

Exocomp


People also ask

What is covariance C#?

In C#, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments. Covariance preserves assignment compatibility and contravariance reverses it.

What is covariance coefficient?

Covariance is an indicator of the extent to which 2 random variables are dependent on each other. A higher number denotes higher dependency. Correlation is a statistical measure that indicates how strongly two variables are related. Values. The value of covariance lies in the range of -∞ and +∞.

What is the covariance symbol?

The covariance matrix is denoted as the uppercase Greek letter Sigma.


2 Answers

Covariance is related to the interplay of subtyping and generics. As your program does not involve generics, it is not an example of covariance.

If U is a subtype of V (e.g. U = Pear and V = Fruit), then a generic type G<T> is said to be covariant in T if G<U> is a subtype of G<V>. For example, IEnumerable<Pear> is a subtype of IEnumerable<Fruit>: something that you can take pears from can be used to take fruit from.

If G reverses the subtyping relation (G<V> is a subtype of G<U>), it is said to be contravariant in T. For instance, Action<Fruit> is a subtype of Action<Pear>: something that you can put fruit in can be used to put pears in.

In your example, neither ICarInterface nor Car has a type parameter that it could be covariant in.

Specifically, in C#, a generic type is covariant in a type parameter T if T is marked with out. It is contravariant in T if T is marked with in.

like image 74
Ruud Avatar answered Sep 25 '22 07:09

Ruud


No, this is not really covariance. This is just the implementation of an interface. Specifically, it is an example of assignment compatibility. Because the Car class implements the ICarInterface interface, a Car object can be assigned to a variable of type ICarInterface. An object of a more-specific type (Car) was assigned to a storage area for a less-specific type (ICarInterface), which works because the two types are compatible for the purposes of assignment.

Covariance is a slightly different thing. A type relationship is covariant if it preserves the ordering of types (from the more-specific to the more-generic). For example, IEnumerable<T> is covariant with respect to type T, so it preserves the ordering of types IEnumerable<Vehicle> (more-generic) and IEnumerable<Car> (more-specific). (In this example, we are of course assuming that Car is a subclass of Vehicle).

Eric Lippert has written an excellent article that distinguishes between covariance and assignment-compatibility. It gets slightly technical and theoretical, but you should definitely read it. I would not do it justice by trying to summarize it any further here.


An easier-to-understand example of covariance (at least in my opinion) is return-type covariance. This is where a derived class's override of a base-class method returns a more specific type. For example:

abstract class Habitat
{
    public abstract Animal ApexPredator();
}

class Savanna : Habitat
{
    public override Lion ApexPredator()
    { ... }
}

class Ocean : Habitat
{
    public override Shark ApexPredator()
    { ... }
}

In this example, the abstract class Habitat has two concrete subclasses: Savanna and Ocean. All habitats have an ApexPredator, which is of type Animal. But in a Savanna object, the apex predator is a Lion, whereas in an Ocean object, the apex predator is a Shark. This is legal and safe because Lion and Shark are both types of Animals.

Unfortunately, C# does not support return type covariance. It is, however, supported by C++ (including C++/CLI), Java, and a number of other object-oriented languages.

Here are some more concrete examples of covariance.

like image 36
Cody Gray Avatar answered Sep 23 '22 07:09

Cody Gray