Search code examples
c#genericsienumerablecovariancecontravariance

How is IEnumerable<T> Contra-variant?


This post (http://blogs.msdn.com/b/brada/archive/2005/01/18/355755.aspx) says IEnumerable<T> is Contra-variant. However type T is co-variant because it is an out parameter. So in what context is IEnumerable<T> Contra-variant ??

Hope I am not confusing! Thanks for the answers in advance!


Solution

  • IEnumerable isn't contra-variant. It's covariant.

    From MSDN (IEnumerable<(Of <(T>)>) Interface) we have that:

    Type Parameters

    out T

    The type of objects to enumerate. This type parameter is covariant. That is, you can use either the type you specified or any type that is more derived.

    From this post we have that:

    The Base Class Library has been updated to support covariance and contravariance in various commonly used interfaces. For example, IEnumerable is now a covariant interface – IEnumerable.

    Sample code:

    // Covariant parameters can be used as result types
    interface IEnumerator<out T>
    {
         T Current { get; }
    
         bool MoveNext();
    }
    
    // Covariant parameters can be used in covariant result types 
    interface IEnumerable<out T>
    {
         IEnumerator<T> GetEnumerator();
    }
    
    // Contravariant parameters can be used as argument types 
    interface IComparer<in T>
    {
         bool Compare(T x, T y); 
    }
    

    For more examples on this, take a look at:

    Covariance and Contravariance FAQ

    Covariance and Contravariance in C#, Part One (Great series of posts by Eric Lippert about Covariance And Contravariance)

    Understanding C# Covariance And Contravariance (3) Samples