Covariance and Contravariance in C#

Covariance and Contravariance in C#

Originally published on the Productive C# blog in 2013.

Covariance

Covariance for generics interfaces is a new feature introduced with the version 4 of the C# language.

The definition for Generics Interfaces

Assuming A is convertible to B,??X is covariant if X<A> is implicitly convertible to X<B>

or similarly

X is covariant if X<A> can be cast to X<B> if B subclasses A

From C# 4, generic interfaces support covariance for type parameters marked with the?out?modifier. This modifier ensures that covariance with interfaces is fully type-safe.

Covariance in interfaces is something that is typically consumed. It’s less common that you need?to write variant interfaces.

The implementation of IEnumerable in the framework has been changed using the out modifier and this makes all the collections in the base class library covariant.

public interface IEnumerable<out T> : IEnumerable        

Example

Suppose that we have two classes in a?inheritance relationship.

No alt text provided for this image

Thanks to this new feature of the language, the following code compiles and works as expected.

No alt text provided for this image
No alt text provided for this image

If you use a previous version of C# the code does not compile and generates a build error.

It is worth noting that previous versions of C# already supported it in arrays and delegates.

If you like this article and interested in taking the next step to master C#, join my?free course on Modern C# 11.

Contravariance

Contravariance is a new feature introduced with the version 4 of the C# language.

The definition

Assuming A is implicitly convertible to B,??X?is contravariant when?X<B>?is implicitly convertible to?X<A>?

or similarly

X is contravariant if X<B> can be cast to X<A> if B subclasses A

From C# 4, generic interfaces support it for type parameters marked with the?in?modifier.?This is supported when the generic type parameter only appears in input positions, designed with the in modifier.

While covariance seems intuitive, contravariance seems useless and wrong.

However, it makes sense and there are situations when is useful.

One example is the IEquatityComparer<T> interface that has been changed using the in modifier.

public interface IEqualityComparer<in T>        

Example

Suppose that we have the following classes.

No alt text provided for this image

Thanks to contravariance the following code compiles and works as expected.

No alt text provided for this image

If you use a previous version of C# the code does not compile and generates a build error.

If you like this article and interested in taking the next step to master C#, join my?free course on Modern C# 11.

Gianluca Gagliano

.Net Full Stack Developer presso EUROGED - Gestione Elettronica Documentale

1 年

A while ago I tried to talk to some colleagues about it and they looked at me like I was an alien! ??

要查看或添加评论,请登录

Andrea Angella的更多文章

  • 15 reasons why you should learn C# in 2024

    15 reasons why you should learn C# in 2024

    Why you should learn C#? This is the question I want to answer in this article. I am Andrea, a Microsoft MVP, Technical…

    8 条评论
  • The importance of defining performance goals

    The importance of defining performance goals

    This post was originally created in the Productive C# blog in 2016. Let’s start from some questions: Is you application…

  • The Singleton Pattern in .NET – Avoid it if you can!

    The Singleton Pattern in .NET – Avoid it if you can!

    This post was originally created in the Productive C# blog in 2012. The Singleton Pattern ensures a class has only one…

    3 条评论
  • Factory Method Pattern in .NET

    Factory Method Pattern in .NET

    This post was originally written on the Productive C# blog in 2012. There is a little bit of confusion around this…

  • The Command Pattern in .NET

    The Command Pattern in .NET

    The post was originally written on the Productive C# blog in 2012. The Command Pattern encapsulates a request as an…

    4 条评论
  • The Adapter Pattern in .NET

    The Adapter Pattern in .NET

    This post was originally written in the Productive C# blog in 2012. The Adapter Pattern converts the interface of a…

    2 条评论
  • The Facade Pattern in .NET

    The Facade Pattern in .NET

    This post was originally written on the Productiove C# blog in 2012. The Facade Pattern provides a unified interface to…

  • The Template Method Pattern in .NET

    The Template Method Pattern in .NET

    This post was originally written in the Productive C# blog in 2013. The Template Method Pattern defines the skeleton of…

    1 条评论
  • The Iterator Pattern in .NET

    The Iterator Pattern in .NET

    This post was originally written in the Productive C# blog in 2013. The Iterator Pattern provides a way to access the…

    1 条评论
  • Value Types and Reference Types in C#

    Value Types and Reference Types in C#

    This post was originally published on the Productive C# blog in 2019. Learn about the difference between value types…

社区洞察

其他会员也浏览了