0% found this document useful (0 votes)
39 views11 pages

Co Contra Variance // Variance: Steven Giesel Steven Giesel

Covariance and contravariance are concepts in C# generics that allow for flexibility when assigning generic types. Covariance allows a method to return a more derived type, while contravariance enables using a more generic (less derived) type than specified. To mark an interface as covariant or contravariant, the out or in keywords are used. Contravariance simplifies code by allowing more reusable components, such as allowing an IHandler<Dog> to be used where an IHandler<Animal> is expected.

Uploaded by

Asef Abuzerli
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
39 views11 pages

Co Contra Variance // Variance: Steven Giesel Steven Giesel

Covariance and contravariance are concepts in C# generics that allow for flexibility when assigning generic types. Covariance allows a method to return a more derived type, while contravariance enables using a more generic (less derived) type than specified. To mark an interface as covariant or contravariant, the out or in keywords are used. Contravariance simplifies code by allowing more reusable components, such as allowing an IHandler<Dog> to be used where an IHandler<Animal> is expected.

Uploaded by

Asef Abuzerli
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 11

Covariance

//

Contravariance

Steven Giesel
Contravariance and

covariance are essential

concepts in C# when dealing

with generics, enabling us to

have more flexibility when

assigning generic types.


Covariance
Allows a method to return a more derived type
than specified by the generic type. In other
words, you can use a derived class where a base
class is expected.

To mark an interface as covariant we can use the


out keyword.

IEnumerable<out T> is covariant, meaning that if


Dog is a subclass of Animal, you can use
IEnumerable<Dog> where IEnumerable<Animal> is
expected.
Contravariance
Enables you to use a more generic (less derived)
type than specified by the generic type. In other
words, you can use a base class where a derived
class is expected.

To mark an interface as covariant we can use the


in keyword.

IComparer<in T> is contravariant, meaning that if


Animal is a base class of Dog, you can use
IComparer<Animal> where IComparer<Dog> is
expected.
What code does it make easier to use
contravariance? Why not using
generic's in this case or directly the
base type?
Contravariance
Contravariance simplifies code by allowing you to
create more reusable and maintainable
components, especially when working with
delegates and interfaces.

While generics alone provide type safety,


contravariance offers an additional layer of
flexibility.

Consider the following example using the base


type directly:
Contravariance
Now imagine we have a method that takes a list
of dogs and an AnimalHandler:

This works fine for an AnimalHandler instance,


but if you want to use a DogHandler, you'll have
to modify the ProcessDogs method. This creates
tight coupling and reduces reusability.

Now let's use contravariance with an interface:


Contravariance
With contravariance, the ProcessDogs method
can accept an IHandler<Dog> instead:
Contravariance

Why not something like this? With


generic constraints?
Contravariance
It's essential to understand the differences
between using constraints and using
contravariance to choose the best approach for
your needs.

By defining IHandler<TAnimal> with a constraint,


you can implement specialized handlers:
Contravariance
The ProcessDogs method will have to be defined
as:

The primary difference is that the ProcessDogs


method is now generic, and the type safety and
flexibility come from the generic type constraint.
In contrast, contravariance provides flexibility
directly in the interface definition without the
need for a generic method.

You might also like