【问题标题】:In C#, why Expression Trees and when do you need to use them?在 C# 中,为什么要使用表达式树以及何时需要使用它们?
【发布时间】:2010-08-23 21:43:47
【问题描述】:

什么时候需要Expression Trees

如果可用,请向我们提供真实世界的样本

【问题讨论】:

标签: c# c#-3.0 lambda expression-trees


【解决方案1】:

例如实现 INotifyPropertyChanged 的​​类型安全实现而不是使用字符串:

public class Sample : TypeSafeNotifyPropertyChanged
{
    private string _text;

    public string Text
    {
        get { return _text; }
        set
        {
            if (_text == value)
                return;

            _text = value;
            OnPropertyChanged(() => Text);
        }
    }
}

public class TypeSafeNotifyPropertyChanged : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)
    {
        PropertyChangedHelper.RaisePropertyChanged(this, propertyExpression, PropertyChanged);
    }
}

public static class PropertyChangedHelper
{
    public static void RaisePropertyChanged<T>(object sender, Expression<Func<T>> propertyExpression, PropertyChangedEventHandler propertyChangedHandler)
    {
        if (propertyChangedHandler == null)
            return;

        if (propertyExpression.Body.NodeType != ExpressionType.MemberAccess)
            return;

        MemberExpression memberExpr = (MemberExpression)propertyExpression.Body;
        string propertyName = memberExpr.Member.Name;
        RaisePropertyChanged(sender, propertyName, propertyChangedHandler);
    }

    private static void RaisePropertyChanged(object sender, string property, PropertyChangedEventHandler propertyChangedHandler)
    {
        if (propertyChangedHandler != null)
            propertyChangedHandler(sender, new PropertyChangedEventArgs(property));
    }
}

【讨论】:

  • 这是表达式树派上用场的一个很好的例子,但我认为①它并不是一个真正的主要例子,它只是碰巧方便; ②你贴的代码太多,解释太少。 ☺
  • 是的,正如 Timwi 所说,所有这些代码的目的仅仅是为了避免人们出现拼写错误/属性名称更改吗?如果是这样的话,我猜这很有用,但我不确定这就是它的用途..
  • 这是为重命名等重构准备的。
  • 在示例() =&gt; Text 中,属性名称Text 可能被错误地替换为任何表达式,它仍然可以正常编译。如果程序员不提供成员的标识符,那么它会默默地在运行时引发事件。那么这种“类型安全”在什么意义上是安全的?
【解决方案2】:

每次您想告诉某个函数需要做什么时,您都需要一个表达式树而不是实际执行它

最好的例子是 LINQ-to-SQL。您传递一个表达式树,以便它可以将此表达式树转换为 SQL。它不会执行表达式,它会检查它并将其转换为 SQL。

【讨论】:

  • 您的第一句话听起来更像是对委托的描述,而不是表达式树。是否“需要完成”以及究竟是什么“完成”完全取决于表达的消费者。
  • 如果我在 C# 中使用 ParameterExpression Length (例如)和字符串的其他 c# 属性(例如:子字符串)构建一个大的纯表达式树 - SQL 仍然知道如何执行它吗?我的意思是:它没有“长度”也没有“子字符串”...... sql 仍然知道如何执行命令吗?
【解决方案3】:

表达式树是对某些执行的描述——实际上它是 DOM。当您执行表达式树时,它会被编译并在之后执行。示例是 LinqToSql。当您为 LinqToSql 构建查询时,您是在 IQueryable 上进行的。结果查询是表达式树。当您执行树时,它被“编译”成 SQL 而不是 .NET 并在数据库上执行。

编辑:Here 你有另一个很好的表达式示例,用于在 EF 查询中包含相关实体。

【讨论】:

    【解决方案4】:

    我最近重构了一个复杂的对象比较器并使用了表达式树。 对象比较器是使用反射实现的,我将其修改为使用反射构建表达式树,然后将表达式树编译为委托。构建和编译委托会产生一些费用,但在编译完成后,它的调用速度几乎是反射解决方案的 100 倍。

    【讨论】:

      猜你喜欢
      • 2012-04-17
      • 2017-04-17
      • 1970-01-01
      • 2014-06-01
      • 2014-10-17
      • 1970-01-01
      • 2016-10-26
      相关资源
      最近更新 更多