1 interface ICovariant<out T>
6 interface IContravariant<in T>
11 interface IBothVariants <out T1, in T2> : ICovariant<T1>, IContravariant<T2>
15 interface IInvariant <T> : ICovariant<T>, IContravariant<T>
19 class BothVariants <T1, T2> : IBothVariants <T1, T2>
21 public BothVariants (T1 foo)
26 public T1 Foo { get; private set; }
28 public int Bar (T2 bar)
30 return bar.GetHashCode () ^ Foo.GetHashCode ();
34 class Invariant <T> : IInvariant<T> where T : new()
36 public T Foo { get { return new T (); } }
38 public int Bar (T bar)
40 return bar.GetHashCode ();
46 public virtual string Fruit { get { return "Apple"; } }
51 public override string Fruit { get { return "Banana"; } }
56 public override string Fruit { get { return "Carrot which I know is not a fruit but you better shut up about it before I cut you"; } }
61 public static int Main ()
66 IBothVariants<A, C> both = new BothVariants<B,B> (b);
68 if (both.Bar (c) != (b.GetHashCode () ^ c.GetHashCode ()))
71 IInvariant<B> neither = new Invariant<B> ();
72 ICovariant<A> co = neither;
73 if (co.Foo.Fruit != "Banana")
76 IContravariant<C> contra = neither;
77 if (contra.Bar (c) != c.GetHashCode ())