Skip to content

Instantly share code, notes, and snippets.

@Porges
Created March 12, 2015 19:30
Show Gist options
  • Save Porges/b374c2238f2f43ffeb75 to your computer and use it in GitHub Desktop.
Save Porges/b374c2238f2f43ffeb75 to your computer and use it in GitHub Desktop.
Something fun you can do with overlapping interfaces...
using System;
using System.Collections.Generic;
namespace TypeTree
{
public interface IGet<out T>
{
T Get { get; }
}
public class Left<T> : IGet<T>
{
private readonly T _left;
public Left(T left)
{
_left = left;
}
T IGet<T>.Get => _left;
}
public class Either<TLeft, TRight> : Left<TLeft>, IGet<TRight>
{
private readonly TRight _right;
public Either(TLeft left, TRight right) : base(left)
{
_right = right;
}
TRight IGet<TRight>.Get => _right;
}
public static class EitherExtensions
{
public static Either<TLeft, TRight> Or<TLeft, TRight>(this TLeft left, TRight right)
=> new Either<TLeft, TRight>(left, right);
// 2
public static T Get<T>(this IGet<T> it) => it.Get;
// 4
public static T Get<T>(this IGet<IGet<T>> it) => it.Get.Get<T>();
// 8
public static T Get<T>(this IGet<IGet<IGet<T>>> it) => it.Get.Get<T>();
// 16
public static T Get<T>(this IGet<IGet<IGet<IGet<T>>>> it) => it.Get.Get<T>();
// 32
public static T Get<T>(this IGet<IGet<IGet<IGet<IGet<T>>>>> it) => it.Get.Get<T>();
}
public static class Program
{
public static void Main()
{
var i_s = 1.Or("2");
Console.WriteLine(i_s.Get<int>());
Console.WriteLine(i_s.Get<string>());
var c_d = '3'.Or(4.0);
Console.WriteLine(c_d.Get<char>());
Console.WriteLine(c_d.Get<double>());
var iscd = i_s.Or(c_d);
Console.WriteLine(iscd.Get<int>());
Console.WriteLine(iscd.Get<string>());
var lasd = (new List<int>()).Or(new int[0]).Or(new HashSet<int>().Or(new Dictionary<int,int>()));
Console.WriteLine(lasd.Get<HashSet<int>>());
var iscdlasd = iscd.Or(lasd);
Console.WriteLine(iscdlasd.Get<string>());
Console.WriteLine(iscdlasd.Get<HashSet<int>>());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment