C# 4.0: Covariance And Contravariance In Generics Made Easy
In my last post, I went through what is variance in .NET 4.0 and C# 4.0 in a rather theoretical way.
Now, I’m going to try to make it a bit more down to earth.
Given:
class Base { }
class Derived : Base { }
Such that:
Trace.Assert(typeof(Base).IsClass && typeof(Derived).IsClass && typeof(Base).IsGreaterOrEqualTo(typeof(Derived)));
-
Covariance
interface ICovariantIn<out T> { }
Trace.Assert(typeof(ICovariantIn<Base>).IsGreaterOrEqualTo(typeof(ICovariantIn<Derived>)));
-
Contravariance
interface IContravariantIn<in T> { }
Trace.Assert(typeof(IContravariantIn<Derived>).IsGreaterOrEqualTo(typeof(IContravariantIn<Base>)));
-
Invariance
interface IInvariantIn<T> { }
Trace.Assert(!typeof(IInvariantIn<Base>).IsGreaterOrEqualTo(typeof(IInvariantIn<Derived>))
&& !typeof(IInvariantIn<Derived>).IsGreaterOrEqualTo(typeof(IInvariantIn<Base>)));
Where:
public static class TypeExtensions
{
public static bool IsGreaterOrEqualTo(this Type self, Type other)
{
return self.IsAssignableFrom(other);
}
}