Firstly, covariance and contravariance in C# only apply to interfaces and delegates.
So your question is really about IDictionary<TKey,TValue>
.
With that out of the way, it’s simplest to just remember that an interface can only be co/contra-variant if all values of a type parameter are either only passed in, or only passed out.
For example (contravariance):
interface IReceiver<in T> // note 'in' modifier
{
void Add(T item);
void Remove(T item);
}
And (covariance):
interface IGiver<out T> // note 'out' modifier
{
T Get(int index);
T RemoveAt(int index);
}
In the case of IDictionary<TKey,TValue>
, both type parameters are used in both an in
and out
capacity, meaning that the interface cannot be covariant or contravariant. It is invariant.
However, the class Dictionary<TKey,TValue>
does implement IEnumerable<T>
which is covariant.
A great reference for this is:
https://learn.microsoft.com/en-us/dotnet/standard/generics/covariance-and-contravariance