zoukankan      html  css  js  c++  java
  • c# 扩展方法奇思妙用基础篇九:Expression 扩展

    http://www.cnblogs.com/ldp615/archive/2011/09/15/expression-extension-methods.html


    .net 中创建 Expression Trees 最简单的方式是使用 lambda 表达式:

    1
    2
    Expression<Func<Person, bool>> exp =
        p => p.Name.Contains("ldp") && p.Birthday.Value.Year > 1990;

    其中 Person 类定义如下:

    1
    2
    3
    4
    public class Person {
        public string Name { get; set; }
        public DateTime? Birthday { get; set; }
    }

     

    但有些时候,要动态创建 Expression Trees,我们要用到 System.Linq.Expressions 命名空间中的 Expression 类

    使用 Expression 类 中的静态方法,前面的 Expression Trees 可如下创建:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var parameter = Expression.Parameter(typeof(Person), "p");
    var left = Expression.Call(
        Expression.Property(parameter, "Name"),
        typeof(string).GetMethod("Contains"),
        Expression.Constant("ldp"));
    var right = Expression.GreaterThan(
        Expression.Property(Expression.Property(Expression.Property(parameter, "Birthday"), "Value"), "Year"),
        Expression.Constant(1990));
    var body = Expression.AndAlso(left, right);
    var lambda = Expression.Lambda<Func<Person, bool>>(body, parameter);

    你应该注意到第 7 行高亮部分,三个重复的 Expression.Property,显得非常臃肿,导致可读性也很差。

    可以用下面几个扩展方法予以简化:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public static class ExpressionExtensions {
        public static Expression AndAlso(this Expression left, Expression right) {
            return Expression.AndAlso(left, right);
        }
        public static Expression Call(this Expression instance, string methodName, params Expression[] arguments) {
            return Expression.Call(instance, instance.Type.GetMethod(methodName), arguments);
        }
        public static Expression Property(this Expression expression, string propertyName) {
            return Expression.Property(expression, propertyName);
        }
        public static Expression GreaterThan(this Expression left, Expression right) {
            return Expression.GreaterThan(left, right);
        }
        public static Expression<TDelegate> ToLambda<TDelegate>(this Expression body, params  ParameterExpression[] parameters) {
            return Expression.Lambda<TDelegate>(body, parameters);
        }
    }

    这五个扩展方法相当简单,没什么技术含量。可以根据自己需要,添加更多的扩展方法。

    前面的代码简化成:

    1
    2
    3
    4
    var parameter = Expression.Parameter(typeof(Person), "p");
    var left = parameter.Property("Name").Call("Contains", Expression.Constant("ldp"));
    var right = parameter.Property("Birthday").Property("Value").Property("Year").GreaterThan(Expression.Constant(1990));
    var lambda = left.AndAlso(right).ToLambda<Func<Person, bool>>(parameter);

    是不是好多了。

    简单编码,快乐生活!

  • 相关阅读:
    peudoclass与pseudo的相同点与不同点
    第一个页面
    自我介绍
    Virtual IP Address 学习记录
    OpenStack 学习记录
    Dubbo学习记录 MAC
    售前 银行
    log4j2 学习记录 Pattern Layout
    Zookeeper学习记录 mac下安装部署
    P2695 骑士的工作
  • 原文地址:https://www.cnblogs.com/swarb/p/9924281.html
Copyright © 2011-2022 走看看