1 // Compiler options: -langversion:future
3 interface ICovariant
<out T
>
8 interface IContravariant
<in T
>
13 interface IBothVariants
<out T1
, in T2
> : ICovariant
<T1
>, IContravariant
<T2
>
17 interface IInvariant
<T
> : ICovariant
<T
>, IContravariant
<T
>
21 class BothVariants
<T1
, T2
> : IBothVariants
<T1
, T2
>
23 public BothVariants (T1 foo
)
28 public T1 Foo { get; private set; }
30 public int Bar (T2 bar
)
32 return bar
.GetHashCode () ^ Foo
.GetHashCode ();
36 class Invariant
<T
> : IInvariant
<T
> where T
: new()
38 public T Foo { get { return new T (); }
}
40 public int Bar (T bar
)
42 return bar
.GetHashCode ();
48 public virtual string Fruit { get { return "Apple"; }
}
53 public override string Fruit { get { return "Banana"; }
}
58 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"; }
}
68 IBothVariants
<A
, C
> both
= new BothVariants
<B
,B
> (b
);
70 if (both
.Bar (c
) != (b
.GetHashCode () ^ c
.GetHashCode ()))
73 IInvariant
<B
> neither
= new Invariant
<B
> ();
74 ICovariant
<A
> co
= neither
;
75 if (co
.Foo
.Fruit
!= "Banana")
78 IContravariant
<C
> contra
= neither
;
79 if (contra
.Bar (c
) != c
.GetHashCode ())