using System;
using System.Collections.Generic;
public class Test
{
public static void Main()
{
var l = new List<Union3<string, DateTime, int>> {
new Union3<string, DateTime, int>(DateTime.Now),
new Union3<string, DateTime, int>(42),
new Union3<string, DateTime, int>("test"),
new Union3<string, DateTime, int>("one more test")
};
foreach (Union3<string, DateTime, int> union in l)
{
string value = union.Match(
str => str,
dt => dt.ToString("yyyy-MM-dd"),
i => i.ToString());
Console.WriteLine("Matched union with value '{0}'", value);
}
}
}
public sealed class Union3<A, B, C>
{
readonly A Item1;
readonly B Item2;
readonly C Item3;
int tag;
public Union3(A item) { Item1 = item; tag = 0; }
public Union3(B item) { Item2 = item; tag = 1; }
public Union3(C item) { Item3 = item; tag = 2; }
public T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h)
{
switch (tag)
{
case 0: return f(Item1);
case 1: return g(Item2);
case 2: return h(Item3);
default: throw new Exception("Unrecognized tag value: " + tag);
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uQ29sbGVjdGlvbnMuR2VuZXJpYzsKIApwdWJsaWMgY2xhc3MgVGVzdAp7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgTWFpbigpCiAgICAgICAgewogICAgICAgIHZhciBsID0gbmV3IExpc3Q8VW5pb24zPHN0cmluZywgRGF0ZVRpbWUsIGludD4+ICB7CiAgICAgICAgICAgICAgICBuZXcgVW5pb24zPHN0cmluZywgRGF0ZVRpbWUsIGludD4oRGF0ZVRpbWUuTm93KSwKICAgICAgICAgICAgICAgIG5ldyBVbmlvbjM8c3RyaW5nLCBEYXRlVGltZSwgaW50Pig0MiksCiAgICAgICAgICAgICAgICBuZXcgVW5pb24zPHN0cmluZywgRGF0ZVRpbWUsIGludD4oInRlc3QiKSwKICAgICAgICAgICAgICAgIG5ldyBVbmlvbjM8c3RyaW5nLCBEYXRlVGltZSwgaW50Pigib25lIG1vcmUgdGVzdCIpCiAgICAgICAgfTsKICAgICAgICAgICAgCiAgICAgICAgICAgIGZvcmVhY2ggKFVuaW9uMzxzdHJpbmcsIERhdGVUaW1lLCBpbnQ+IHVuaW9uIGluIGwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmluZyB2YWx1ZSA9IHVuaW9uLk1hdGNoKAogICAgICAgICAgICAgICAgICAgIHN0ciA9PiBzdHIsCiAgICAgICAgICAgICAgICAgICAgZHQgPT4gZHQuVG9TdHJpbmcoInl5eXktTU0tZGQiKSwKICAgICAgICAgICAgICAgICAgICBpID0+IGkuVG9TdHJpbmcoKSk7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBDb25zb2xlLldyaXRlTGluZSgiTWF0Y2hlZCB1bmlvbiB3aXRoIHZhbHVlICd7MH0nIiwgdmFsdWUpOwogICAgICAgICAgICB9CiAgICAgICAgCiAgICAgICAgfSAgICAgICAKfQogCnB1YmxpYyBzZWFsZWQgY2xhc3MgVW5pb24zPEEsIEIsIEM+CnsKICAgICAgICByZWFkb25seSBBIEl0ZW0xOwogICAgICAgIHJlYWRvbmx5IEIgSXRlbTI7CiAgICAgICAgcmVhZG9ubHkgQyBJdGVtMzsKICAgICAgICBpbnQgdGFnOwogCiAgICAgICAgcHVibGljIFVuaW9uMyhBIGl0ZW0pIHsgSXRlbTEgPSBpdGVtOyB0YWcgPSAwOyB9CiAgICAgICAgcHVibGljIFVuaW9uMyhCIGl0ZW0pIHsgSXRlbTIgPSBpdGVtOyB0YWcgPSAxOyB9CiAgICAgICAgcHVibGljIFVuaW9uMyhDIGl0ZW0pIHsgSXRlbTMgPSBpdGVtOyB0YWcgPSAyOyB9CiAKICAgICAgICBwdWJsaWMgVCBNYXRjaDxUPihGdW5jPEEsIFQ+IGYsIEZ1bmM8QiwgVD4gZywgRnVuYzxDLCBUPiBoKQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoICh0YWcpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgMDogcmV0dXJuIGYoSXRlbTEpOwogICAgICAgICAgICAgICAgY2FzZSAxOiByZXR1cm4gZyhJdGVtMik7CiAgICAgICAgICAgICAgICBjYXNlIDI6IHJldHVybiBoKEl0ZW0zKTsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRocm93IG5ldyBFeGNlcHRpb24oIlVucmVjb2duaXplZCB0YWcgdmFsdWU6ICIgKyB0YWcpOwogICAgICAgICAgICB9CiAgICAgICAgfQogfQ==