Consider the code snippet.
IList<String> obj=new List<string>();
IEnumerable<Object> obj1 = obj;
But if i write ICollection<Object> obj2 = obj; it throws me a compile time error.
Cannot implicitly convert type ‘
System.Collections.Generic.IList<string>‘ to ‘System.Collections.Generic.ICollection<object>‘.
Why is this behavior since List<T> implements both IEnumerable<T> and ICollection<T> and also IList<T> is defined as
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable
{
T this[int index] { get; set; }
int IndexOf(T item);
void Insert(int index, T item);
void RemoveAt(int index);
}
ICollection<T>is not covariant on the type parameter, whereasIEnumerable<T>is. If you look at their declarations (ICollection, IEnumerable) you can see thatIEnumerable<T>uses theoutkeyword onT, whileICollection<T>does not.This makes sense if you think about it, since (roughly speaking) covariance is safe when the interface will only be used to read objects (and thus the
outkeyword).IEnumerable<T>clearly meets that criterion, whereasICollection<T>is quite the opposite.As an example of what could go wrong (using your example):
Remember: covariance is not the same as inheritance. Just because two classes or interfaces share an inheritance relation does not mean their type parameters share the same variance characteristics.