表达式树

  表达式简述: 

    表达式目录树以数据形式表示语言级别代码。数据存储在树形结构中。表达式目录树中的每个节点都表示一个表达式.(来自MSDN)

    先用表API生成一个简单方法 : int  add(int a,int b){return a+b);

ParameterExpression p1 = Expression.Parameter(typeof (int), "a");
            ParameterExpression p2 = Expression.Parameter(typeof(int), "b");
            BinaryExpression add = Expression.Add(p1, p2);

上面表达式的创建已经完成。
    表达式的执行:

    MSDN上讲 :只能执行表示 lambda 表达式的表达式树。 表示 lambda 表达式的表达式树属于 LambdaExpression 或 Expression<TDelegate> 类型。 若要执行这些表达式树,需要调用 Compile 方法来创建一个可执行委托,然后调用该委托。

如果表达式树不表示一个 lambda 表达式,则可以通过调用 Lambda<TDelegate>(Expression, IEnumerable<ParameterExpression>) 方法,创建一个以原始表达式树作为其主体的新 lambda 表达式。 然后,即可按照本节前面所述执行该 lambda 表达式。

        

  Expression<Func<int, int, int>> excute = Expression.Lambda<Func<int, int, int>>(add,new ParameterExpression[]{p1,p2});
            Func<int, int, int> fc=excute.Compile();

调用委托 既可以执行我们创建的表达式树。

 

方法调用:

   对于下面此方法调用

 

 class Program
    {
        public void MethodEx(int a, int b,int c)
        {

        }
}

 NewExpression nty = Expression.New(typeof(Program));
            List<ParameterExpression> p = new List<ParameterExpression>
            {
                   Expression.Parameter(typeof(int),"a"),
                    Expression.Parameter(typeof(int),"b"),
                  Expression.Parameter(typeof(int),"c")

            };
            MethodCallExpression mc = Expression.Call(nty, typeof(Program).GetMethod("MethodEx"), p);
            var sd = Expression.Lambda(mc, p);

            var s = sd.Compile();

更通用的方法调用:

 public static Delegate CreateDelegate(MethodInfo methodInfo)
        {
            if (methodInfo == null)
                throw new ArgumentNullException("Error");

            var parameters = methodInfo.GetParameters();
            var paramExpressions = new List<ParameterExpression>();
            int i = 0;
            foreach (var p in parameters)
            {
                paramExpressions.Add(Expression.Parameter(p.ParameterType, i.ToString()));
                ++i;
            }
            MethodCallExpression callExpression=null;
            if (methodInfo.IsStatic)
            {

                callExpression = Expression.Call(methodInfo, paramExpressions);
            }
            else
            {
                var instanceExpression = Expression.New(methodInfo.ReflectedType);
                callExpression = Expression.Call(instanceExpression, methodInfo, paramExpressions);
            }
            var lambdaExpression = Expression.Lambda(callExpression, paramExpressions);
            return lambdaExpression.Compile();
        }

 调用: var d = CreateDelegate(typeof(Program).GetMethod("MethodEx"));

对于方法的反射调用,可以使用上面表达式树替换

posted @ 2014-07-23 17:08  坚硬的鸡蛋  阅读(168)  评论(0编辑  收藏  举报