If a covariant type appears as an output, the containing type is covariant. Producing a producer of Ts is like producing Ts.
interface IReturnCovariant<out T>
{
IEnumerable<T> GetTs();
}
If a contravariant type appears as an output, the containing type is contravariant. Producing a consumer of Ts is like consuming Ts.
interface IReturnContravariant<in T>
{
IComparer<T> GetTComparer();
}
If a covariant type appears as an input, the containing type is contravariant. Consuming a producer of Ts is like consuming Ts.
interface IAcceptCovariant<in T>
{
void ProcessTs(IEnumerable<T> ts);
}
If a contravariant type appears as an input, the containing type is covariant. Consuming a consumer of Ts is like producing Ts.
interface IAcceptContravariant<out T>
{
void CompareTs(IComparer<T> tComparer);
}