using System; using System.Collections.Generic; using System.Linq; namespace LinqExtensions { public static class Extensions { public interface IEqualTo { IEnumerable Alias(Func composite); } public interface IOn { IEqualTo EqualTo(Func toFunction); } public interface IJoin { IOn On(Func fromFunction); } private class Join : IJoin { public IEnumerable FromList { get; set; } public IEnumerable ToList { get; set; } public IOn On(Func fromFunction) { return new On { Join = this, FromFunction = fromFunction }; } } private class On : IOn { public IJoin Join { get; set; } public Func FromFunction { get; set; } public IEqualTo EqualTo(Func toFunction) { return new Is { Join = Join, FromFunction = FromFunction, ToFunction = toFunction }; } } private class Is : IEqualTo { public IJoin Join { get; set; } public Func FromFunction { get; set; } public Func ToFunction { get; set; } public IEnumerable Alias(Func composite) { var join = ((Join)Join); return join.FromList.Join(join.ToList, FromFunction, ToFunction, composite); } } public static IJoin JoinTo(this IEnumerable joinFrom, IEnumerable joinTo) { return new Join { FromList = joinFrom, ToList = joinTo }; } } }