using System;
interface ICovar<out T> {
T Get();
// void Set(T value); // Can't have arguments of covariant type
}
interface IContravar<in T> {
// T Get(); // Can't have return type of contravariant type
void Set(T value);
public class Program
{
public static void Main()
//===============================================================
// Covariance
// ICovar<T> means ICovar<any-type-that-inherits-from-T>
ICovar<string> str = null;
ICovar<object> obj = null;
// str = obj; // Bad: object does NOT inherit from string(T)
obj = str; // Good: string DOES inherit from object(T)
// Contravariance
// IContravar<T> means IContravar<any-type-T-inherits-from>
IContravar<string> str = null;
IContravar<object> obj = null;
str = obj; // Good: object IS a base class of string
// obj = str; // Bad: string is NOT a base class of object