zoukankan      html  css  js  c++  java
  • 解析入口参数为实体的表达式树

          在学习LINQ的时候碰到了解析表达式树的问题,书上的例子中入口参数为一个单一变量,这个在MSDN中给出了示例代码:

    MSDN官方示例:

    // Add the following using directive to your code file:
    // using System.Linq.Expressions;
    // Create an expression tree.
    Expression<Func<int, bool>> exprTree = num => num <5;
    // Decompose the expression tree.
    ParameterExpression param = (ParameterExpression)exprTree.Parameters[0];
    BinaryExpression operation
    = (BinaryExpression)exprTree.Body;
    ParameterExpression left
    = (ParameterExpression)operation.Left;
    ConstantExpression right
    = (ConstantExpression)operation.Right;
    Console.WriteLine(
    "Decomposed expression: {0} => {1} {2} {3}",
    param.Name, left.Name, operation.NodeType, right.Value);
    // This code produces the following output:
    // Decomposed expression: num => num LessThan 5

           这里表达式的入口参数是一个int型的变量,表达式左边就是这个参数本身,右边是一个常量,因此用

                  ParameterExpression left = (ParameterExpression)operation.Left;

                  ConstantExpression right = (ConstantExpression)operation.Right;

    来解析即可,但如果入口是一个实体呢,这种情况很常见,应该怎么解析呢,通过向高人请教,最后用编译表达式树终于解决了这个问题:

        //实体类
        public class T
        {
            
    public int ID { getset; }
            
    public string Name { getset; }
        }

        
    //解析表达式树类
        public class Test
        {
            
    public void ExpressionTest(Expression<Func<T, bool>> exprTree)
            {
                ParameterExpression param 
    = (ParameterExpression)exprTree.Parameters[0];
                BinaryExpression operation 
    = (BinaryExpression)exprTree.Body;
                MemberExpression left 
    = (MemberExpression)operation.Left;
                MemberExpression right 
    = (MemberExpression)operation.Right;

                var result
    =Expression.Lambda(right).Compile().DynamicInvoke();
                Console.WriteLine(
    "Decomposed expression:{0}=>{1} {2} {3}",
                    param.Name,left.Member.Name,operation.NodeType,result.ToString());
            }
        }

        
    //调用
        public class Program
        {
            
    static void Main(string[] args)
            {
                Test test 
    = new Test();
                T t 
    = new T() { ID = 1, Name = "abc" };
                test.ExpressionTest(o 
    => o.ID == t.ID);
                test.ExpressionTest(o 
    => o.Name == t.Name);            
                Console.Read();
            }
        }

     运行结果如下:

     

          园子中有位朋友提供了另外一种方法(http://home.cnblogs.com/q/22976/),不过那个方法有一定缺陷,要依赖于实体类型,如果像上面代码中那样把表达式做为一个参数就无能为力了。

  • 相关阅读:
    28完全背包+扩展欧几里得(包子凑数)
    HDU 3527 SPY
    POJ 3615 Cow Hurdles
    POJ 3620 Avoid The Lakes
    POJ 3036 Honeycomb Walk
    HDU 2352 Verdis Quo
    HDU 2368 Alfredo's Pizza Restaurant
    HDU 2700 Parity
    HDU 3763 CDs
    POJ 3279 Fliptile
  • 原文地址:https://www.cnblogs.com/artwl/p/1985521.html
Copyright © 2011-2022 走看看