public static void Main()
Either<X, Y> dontKnowWhich = GetXOrY();
PrintEither(dontKnowWhich);
public static Either<X, Y> GetXOrY()
if(rand.Next(1,3) == 1) return new X();
public static void PrintEither(Either<X, Y> either)
var result = either.Match((x) => x.Value, (y) => y.Value);
Console.WriteLine(result);
public string Value => "X";
public string Value => "Y";
public class Either<T1, T2>
object _value { get;set; }
public TResult Match<TResult>(Func<T1, TResult> f1, Func<T2, TResult> f2)
if(index == 0) return f1((T1)_value);
if(index == 1) return f2((T2)_value);
public static implicit operator Either<T1, T2>(T1 t1) => new Either<T1, T2>(t1);
public static implicit operator Either<T1, T2>(T2 t2) => new Either<T1, T2>(t2);