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