1. 程式人生 > >Util應用程式框架公共操作類(九):Lambda表示式擴充套件

Util應用程式框架公共操作類(九):Lambda表示式擴充套件

using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; using Util.Lambdas; namespace Util { /// <summary> /// 表示式擴充套件 /// </summary> public static partial class Extensions { #region Property(屬性表示式) /// <summary> ///
建立屬性表示式 /// </summary> /// <param name="expression">表示式</param> /// <param name="propertyName">屬性名,支援多級屬性名,與句點分隔,範例:Customer.Name</param> public static Expression Property( this Expression expression, string propertyName ) { if ( propertyName.All( t => t != '
.' ) ) return Expression.Property( expression, propertyName ); var propertyNameList = propertyName.Split( '.' ); Expression result = null; for ( int i = 0; i < propertyNameList.Length; i++ ) { if ( i == 0 ) { result
= Expression.Property( expression, propertyNameList[0] ); continue; } result = result.Property( propertyNameList[i] ); } return result; } /// <summary> /// 建立屬性表示式 /// </summary> /// <param name="expression">表示式</param> /// <param name="member">屬性</param> public static Expression Property( this Expression expression, MemberInfo member ) { return Expression.MakeMemberAccess( expression, member ); } #endregion #region Operation(操作) /// <summary> /// 操作 /// </summary> /// <param name="left">左運算元</param> /// <param name="operator">運算子</param> /// <param name="value"></param> public static Expression Operation( this Expression left, Operator @operator, object value ) { switch ( @operator ) { case Operator.Equal: return left.Equal( value ); case Operator.NotEqual: return left.NotEqual( value ); case Operator.Greater: return left.Greater( value ); case Operator.Less: return left.Less( value ); case Operator.GreaterEqual: return left.GreaterEqual( value ); case Operator.LessEqual: return left.LessEqual( value ); case Operator.Contains: return left.Call( "Contains", value ); case Operator.Starts: return left.StartsWith( value ); case Operator.Ends: return left.EndsWith( value ); } throw new NotImplementedException(); } #endregion #region StartsWith(頭匹配) /// <summary> /// 頭匹配 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression StartsWith( this Expression left, object value ) { return left.Call( "StartsWith", new[] { typeof( string ) }, value ); } #endregion #region EndsWith(尾匹配) /// <summary> /// 尾匹配 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression EndsWith( this Expression left, object value ) { return left.Call( "EndsWith", new[] { typeof( string ) }, value ); } #endregion #region Call(呼叫方法表示式) /// <summary> /// 建立呼叫方法表示式 /// </summary> /// <param name="instance">呼叫的例項</param> /// <param name="methodName">方法名</param> /// <param name="values">引數值列表</param> public static Expression Call( this Expression instance, string methodName, params Expression[] values ) { return Expression.Call( instance, instance.Type.GetMethod( methodName ), values ); } /// <summary> /// 建立呼叫方法表示式 /// </summary> /// <param name="instance">呼叫的例項</param> /// <param name="methodName">方法名</param> /// <param name="values">引數值列表</param> public static Expression Call( this Expression instance, string methodName, params object[] values ) { if ( values == null || values.Length == 0 ) return Expression.Call( instance, instance.Type.GetMethod( methodName ) ); return Expression.Call( instance, instance.Type.GetMethod( methodName ), values.Select( Expression.Constant ) ); } /// <summary> /// 建立呼叫方法表示式 /// </summary> /// <param name="instance">呼叫的例項</param> /// <param name="methodName">方法名</param> /// <param name="paramTypes">引數型別列表</param> /// <param name="values">引數值列表</param> public static Expression Call( this Expression instance, string methodName, Type[] paramTypes, params object[] values ) { if ( values == null || values.Length == 0 ) return Expression.Call( instance, instance.Type.GetMethod( methodName, paramTypes ) ); return Expression.Call( instance, instance.Type.GetMethod( methodName, paramTypes ), values.Select( Expression.Constant ) ); } #endregion #region Equal(等於表示式) /// <summary> /// 建立等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression Equal( this Expression left, Expression right ) { return Expression.Equal( left, right ); } /// <summary> /// 建立等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression Equal( this Expression left, object value ) { return left.Equal( Lambda.Constant( left, value ) ); } #endregion #region NotEqual(不等於表示式) /// <summary> /// 建立不等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression NotEqual( this Expression left, Expression right ) { return Expression.NotEqual( left, right ); } /// <summary> /// 建立不等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression NotEqual( this Expression left, object value ) { return left.NotEqual( Lambda.Constant( left, value ) ); } #endregion #region Greater(大於表示式) /// <summary> /// 建立大於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression Greater( this Expression left, Expression right ) { return Expression.GreaterThan( left, right ); } /// <summary> /// 建立大於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression Greater( this Expression left, object value ) { return left.Greater( Lambda.Constant( left, value ) ); } #endregion #region Less(小於表示式) /// <summary> /// 建立小於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression Less( this Expression left, Expression right ) { return Expression.LessThan( left, right ); } /// <summary> /// 建立小於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression Less( this Expression left, object value ) { return left.Less( Lambda.Constant( left, value ) ); } #endregion #region GreaterEqual(大於等於表示式) /// <summary> /// 建立大於等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression GreaterEqual( this Expression left, Expression right ) { return Expression.GreaterThanOrEqual( left, right ); } /// <summary> /// 建立大於等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression GreaterEqual( this Expression left, object value ) { return left.GreaterEqual( Lambda.Constant( left, value ) ); } #endregion #region LessEqual(小於等於表示式) /// <summary> /// 建立小於等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression LessEqual( this Expression left, Expression right ) { return Expression.LessThanOrEqual( left, right ); } /// <summary> /// 建立小於等於運算表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="value"></param> public static Expression LessEqual( this Expression left, object value ) { return left.LessEqual( Lambda.Constant( left, value ) ); } #endregion #region Compose(組合表示式) /// <summary> /// 組合表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="first">左運算元</param> /// <param name="second">右運算元</param> /// <param name="merge">合併操作</param> internal static Expression<T> Compose<T>( this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge ) { var map = first.Parameters.Select( ( f, i ) => new { f, s = second.Parameters[i] } ).ToDictionary( p => p.s, p => p.f ); var secondBody = ParameterRebinder.ReplaceParameters( map, second.Body ); return Expression.Lambda<T>( merge( first.Body, secondBody ), first.Parameters ); } #endregion #region And(與表示式) /// <summary> /// 與操作表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression And( this Expression left, Expression right ) { if ( left == null ) return right; if ( right == null ) return left; return Expression.AndAlso( left, right ); } /// <summary> /// 與操作表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression<Func<T, bool>> And<T>( this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right ) { if ( left == null ) return right; if ( right == null ) return left; return left.Compose( right, Expression.AndAlso ); } #endregion #region Or(或表示式) /// <summary> /// 或操作表示式 /// </summary> /// <param name="left">左運算元</param> /// <param name="right">右運算元</param> public static Expression Or( this Expression left, Expression right ) { return Expression.OrElse( left, right ); } /// <summary> /// 或操作表示式 /// </summary> /// <typeparam name="T">物件型別</typeparam> /// <param name="first">左運算元</param> /// <param name="second">右運算元</param> /// <returns></returns> public static Expression<Func<T, bool>> Or<T>( this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second ) { return first.Compose( second, Expression.OrElse ); } #endregion #region Value(獲取lambda表示式的值) /// <summary> /// 獲取lambda表示式的值 /// </summary> /// <typeparam name="T">物件型別</typeparam> public static object Value<T>( this Expression<Func<T, bool>> expression ) { return Lambda.GetValue( expression ); } #endregion #region ToLambda(建立Lambda表示式) /// <summary> /// 建立Lambda表示式 /// </summary> /// <typeparam name="TDelegate">委託型別</typeparam> /// <param name="body">表示式</param> /// <param name="parameters">引數列表</param> public static Expression<TDelegate> ToLambda<TDelegate>( this Expression body, params ParameterExpression[] parameters ) { return Expression.Lambda<TDelegate>( body, parameters ); } #endregion } }