internal static Delegate BinaryOperationHelper <Delegate, Left, Right, Return>(BinaryOperationHelperDelegate operation) { // shared expressions ParameterExpression _left = Expression.Parameter(typeof(Left)); ParameterExpression _right = Expression.Parameter(typeof(Right)); LabelTarget _label = Expression.Label(typeof(Return)); // code builder ListLinked <Expression> expressions = new ListLinked <Expression>(); // null checks if (!typeof(Left).IsValueType) // is nullable? { expressions.Add( Expression.IfThen( Expression.Equal(_left, Expression.Constant(null, typeof(Left))), Expression.Throw(Expression.New(typeof(System.ArgumentNullException).GetConstructor(new System.Type[] { typeof(string) }), Expression.Constant("left"))))); } if (!typeof(Right).IsValueType) // is nullable? { expressions.Add( Expression.IfThen( Expression.Equal(_right, Expression.Constant(null, typeof(Right))), Expression.Throw(Expression.New(typeof(System.ArgumentNullException).GetConstructor(new System.Type[] { typeof(string) }), Expression.Constant("right"))))); } // code expressions.Add(operation(_left, _right, _label)); expressions.Add(Expression.Label(_label, Expression.Constant(default(Return), typeof(Return)))); // build expression Expression expression = Expression.Block(expressions.ToArray()); // compile return(Expression.Lambda <Delegate>(expression, _left, _right).Compile()); }
internal static Delegate UnaryOperationHelper <Delegate, Operand, Return>(UnaryOperationHelperDelegate operation) { // shared expressions ParameterExpression _operand = Expression.Parameter(typeof(Operand)); LabelTarget _label = Expression.Label(typeof(Return)); // code builder ListLinked <Expression> expressions = new ListLinked <Expression>(); // null checks if (!typeof(Operand).IsValueType) // is nullable? { expressions.Add( Expression.IfThen( Expression.Equal(_operand, Expression.Constant(null, typeof(Operand))), Expression.Throw(Expression.New(typeof(System.ArgumentNullException).GetConstructor(new System.Type[] { typeof(string) }), Expression.Constant("operand"))))); } // code expressions.Add(operation(_operand, _label)); expressions.Add(Expression.Label(_label, Expression.Constant(default(Return)))); // build return(Expression.Lambda <Delegate>( Expression.Block(expressions.ToArray()), _operand).Compile()); }