在C#中,为什么表达树以及何时需要使用它们?

时间:2010-08-23 21:43:48

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

当我需要Expression Trees

请向我们提供真实世界样本(如果有)

4 个答案:

答案 0 :(得分:8)

例如,实现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));
    }
}

答案 1 :(得分:7)

每次你想要告诉某个功能需要做什么而不是实际做时,你需要一个表达式树。

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

答案 2 :(得分:5)

表达式树是一些执行的描述 - 实际上它是DOM。执行表达式树时,它会被编译,然后执行。示例是LinqToSql。当您为LinqToSql构建查询时,您正在IQueryable上执行此操作。结果查询是表达式树。当您执行树时,它被“编译”为SQL而不是.NET并在数据库上执行。

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

答案 3 :(得分:1)

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