Skip to content

Generic covariant C# 4.0type safety

Prefix a generic type parameter with `out` so superclasses can be substituted.

Object-oriented programming allows types to be substituted in some scenarios. For example, if a method returns us an Account it is fine for that method to return us a SavingsAccount instead.

This is known as Covariance and has been supported since C# 1.0 for normal types. Generic covariance brings covariance to generic types.

Let us consider IList<T>. We can never assign anything implementing this interface to IList<SubOfT> because it both accepts arguments of T (Add) and returns T (for Get). No type except T can be both a subclass and a superclass.

But what about a interface that only returns instances of T like an enumerable? With generic covariance we can do this!

Code

C#
IEnumerable<Accounts> accounts = getAccounts<SavingsAccounts>();
foreach(var account in accounts)
    PrintStatement(account);
C#
IEnumerable<SavingsAccounts> accounts = getAccounts<SavingsAccounts>();
foreach(var account in accounts)
    PrintStatement((Account)account);

This was achieved in .NET by Microsoft changing IEnumerable<T> to IEnumerable<out T>.

Notes

  • The reverse of this - accepting a more specific argument rather than having a more specific one returned to you - is Generic contravariance C# 4.0

More information