// Variant type parameters could be declared in interfaces or delegates only!
interface ICovariant<out T> { }
class Covariant<T> : ICovariant<T> { }
interface IContravariant<in T> { }
class Contravariant<T> : IContravariant<T> { }
interface IInvariant<T> { }
class Invariant<T> : IInvariant<T> { }
class Program { private static void Covariant( /* out */) { ICovariant<object> obj = new Covariant<object>(); ICovariant<string> str = new Covariant<string>();
// You can assign "Derived" to "Base" obj = str; str = obj; // error }
private static void Contravariant( /* in */) { IContravariant<object> obj = new Contravariant<object>(); IContravariant<string> str = new Contravariant<string>();
// You can assign "Base" to "Derived" str = obj; obj = str; // error }
private static void Invariant( /* none */) { IInvariant<object> obj = new Invariant<object>(); IInvariant<string> str = new Invariant<string>();
// You can't do any assign obj = str; // error str = obj; // error } }