Util應用程式框架公共操作類(九):Lambda表示式擴充套件
阿新 • • 發佈:2018-12-27
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
}
}