#region Using Directives using System; using System.Collections.Generic; using System.Linq.Expressions; #endregion namespace BlogPosts { public class Sequence { public static IEnumerable From( T min, T max ) { return From( min, max, i => Operator.Add( i, 1 ) ); } public static IEnumerable From( T min, T max, T increment ) { return From( min, max, i => Operator.Add( i, increment ), default( T ) ); } public static IEnumerable From( T min, T max, Func increment ) { return From( min, max, increment, default( T ) ); } public static IEnumerable From( T min, T max, T increment, T offset ) { return From( min, max, i => Operator.Add( i, increment ), offset ); } public static IEnumerable From( T min, T max, Func increment, T offset ) { return From( min, max, increment, i => true, offset ); } public static IEnumerable From( T min, T max, T increment, Func filter ) { return From( min, i => Operator.LessThan( i, max ), i => Operator.Add( i, increment ), filter ); } public static IEnumerable From( T min, Func max, T increment ) { return From( min, max, i => Operator.Add( i, increment ) ); } public static IEnumerable From( T min, T max, T increment, Func filter, T offset ) { return From( Operator.Add( min, offset ), i => Operator.LessThan( i, max ), i => Operator.Add( i, increment ), filter ); } public static IEnumerable From( T min, T max, Func increment, Func filter ) { return From( min, i => Operator.LessThan( i, max ), increment, filter ); } public static IEnumerable From( T min, T max, Func increment, Func filter, T offset ) { return From( Operator.Add( min, offset ), i => Operator.LessThan( i, max ), increment, filter ); } public static IEnumerable From( T min, Func max, Func increment ) { return From( min, max, increment, i => true ); } public static IEnumerable From( T min, Func max, Func increment, Func filter ) { for ( T i = min; max( i ); i = increment( i ) ) { if ( filter( i ) ) { yield return i; } } } #region Nested type: Operator private class Operator { public static T Add( T lhs, T rhs ) { return Operators.AddDelegate.Invoke( lhs, rhs ); } public static TLhs Add( TLhs lhs, TRhs rhs ) { return Operators.AddDelegate.Invoke( lhs, rhs ); } public static bool LessThan( T lhs, T rhs ) { return Operators.LessThanDelegate.Invoke( lhs, rhs ); } #region Nested type: Operators private class Operators { public static readonly Func AddDelegate; public static readonly Func LessThanDelegate; static Operators() { AddDelegate = CreateAddDelegate(); LessThanDelegate = CreateLessThanDelegate(); } private static Func CreateAddDelegate() { ParameterExpression lhs = Expression.Parameter( typeof (T), "lhs" ); ParameterExpression rhs = Expression.Parameter( typeof (T), "rhs" ); return Expression.Lambda>( new Func( Expression.Add ) .Invoke( lhs, rhs ), new[] {lhs, rhs} ) .Compile(); } private static Func CreateLessThanDelegate() { ParameterExpression lhs = Expression.Parameter( typeof (T), "lhs" ); ParameterExpression rhs = Expression.Parameter( typeof (T), "rhs" ); return Expression.Lambda>( new Func( Expression.LessThan ) .Invoke( lhs, rhs ), new[] {lhs, rhs} ) .Compile(); } } private class Operators { public static readonly Func AddDelegate; static Operators() { AddDelegate = CreateAddDelegate(); } private static Func CreateAddDelegate() { ParameterExpression lhs = Expression.Parameter( typeof (TValue), "lhs" ); ParameterExpression rhs = Expression.Parameter( typeof (TResult), "rhs" ); return Expression.Lambda>( new Func( Expression.Add ) .Invoke( lhs, rhs ), new[] {lhs, rhs} ) .Compile(); } } #endregion } #endregion } }