a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
83 lines
1.4 KiB
C#
83 lines
1.4 KiB
C#
interface ICovariant<out T>
|
|
{
|
|
T Foo { get; }
|
|
}
|
|
|
|
interface IContravariant<in T>
|
|
{
|
|
int Bar (T bar);
|
|
}
|
|
|
|
interface IBothVariants <out T1, in T2> : ICovariant<T1>, IContravariant<T2>
|
|
{
|
|
}
|
|
|
|
interface IInvariant <T> : ICovariant<T>, IContravariant<T>
|
|
{
|
|
}
|
|
|
|
class BothVariants <T1, T2> : IBothVariants <T1, T2>
|
|
{
|
|
public BothVariants (T1 foo)
|
|
{
|
|
Foo = foo;
|
|
}
|
|
|
|
public T1 Foo { get; private set; }
|
|
|
|
public int Bar (T2 bar)
|
|
{
|
|
return bar.GetHashCode () ^ Foo.GetHashCode ();
|
|
}
|
|
}
|
|
|
|
class Invariant <T> : IInvariant<T> where T : new()
|
|
{
|
|
public T Foo { get { return new T (); } }
|
|
|
|
public int Bar (T bar)
|
|
{
|
|
return bar.GetHashCode ();
|
|
}
|
|
}
|
|
|
|
class A
|
|
{
|
|
public virtual string Fruit { get { return "Apple"; } }
|
|
}
|
|
|
|
class B : A
|
|
{
|
|
public override string Fruit { get { return "Banana"; } }
|
|
}
|
|
|
|
class C : B
|
|
{
|
|
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"; } }
|
|
}
|
|
|
|
public class Test
|
|
{
|
|
public static int Main ()
|
|
{
|
|
var b = new B ();
|
|
var c = new C ();
|
|
|
|
IBothVariants<A, C> both = new BothVariants<B,B> (b);
|
|
|
|
if (both.Bar (c) != (b.GetHashCode () ^ c.GetHashCode ()))
|
|
return 1;
|
|
|
|
IInvariant<B> neither = new Invariant<B> ();
|
|
ICovariant<A> co = neither;
|
|
if (co.Foo.Fruit != "Banana")
|
|
return 2;
|
|
|
|
IContravariant<C> contra = neither;
|
|
if (contra.Bar (c) != c.GetHashCode ())
|
|
return 3;
|
|
|
|
return 0;
|
|
}
|
|
}
|