如何订阅一个表达式树内的对象的事件?(How do I subscribe to an event

2019-09-29 03:10发布

对不起,我想不出更好的标题。 这是一个问题的两个部分,只有有意义起来。

说我有这样一个构造函数

public Fact(INotifyPropertyChanged observable, Func<bool> predicate)
{
    this.predicate = predicate;
    observable.PropertyChanged += (sender, args) =>
                     PropertyChanged(this, new PropertyChangedEventArgs("Value"));

}

这是如何使用它

new Fact(Model.AllowEditing, () => Model.AllowEditing);

其中AllowEditing是一种类型的INotifyPropertyChanged的

我想重构构造成

public Fact(Expression<Func<bool>> expression)

所以可以这样调用

new Fact(() => Model.AllowEditing);

现在的问题是如何解析表达式得到“可观察的”出表达式树然后订阅其事件?

上面的代码是不是我的,它来自从Ayende的例子最近的例子,这里是喜欢完整源代码,如果有人想看看是如何被使用的事实类http://github.com/ayende / Effectus

Answer 1:

基本上,你在这种情况下所需要的对象存储在expression.Body.Expression。 您需要编译和执行表达式目录树得到它。 此外,您可能需要检查的类型是否真正实现你的接口是否谓语是你的真正所期待的。

这里是一个非常粗糙的代码:

public Fact(Expression<Func<bool>> predicate)
{        
    this.predicate = predicate;
    MemberExpression body = predicate.Body as MemberExpression;

    // Check that you get a valid lambda expression, 
    // like object.Member, not something like !object.Member
    if (body == null) 
         throw new ArgumentException("'" + predicate + "': is not a valid expression for this method");
    var type = body.Expression.Type;

    // Check if type implements INotifyPropertyChanged using reflection  
    // ...

    INotifyPropertyChanged observable = 
    Expression.Lambda<Func<INotifyPropertyChanged>>(body.Expression).Compile()();
    //...
}


文章来源: How do I subscribe to an event of an object inside an expression tree?