How do I subscribe to an event of an object inside an expression tree?

二次信任 提交于 2019-12-24 06:31:08

问题


Sorry I couldn't think of a better title. This is a two part question that only make sense together.

Say I have a constructor like this

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

}

and this is how it's used

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

where AllowEditing is a type of INotifyPropertyChanged

I would like to refactor the constructor into

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

So it can be call like this

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

The question is how to parse that expression to get "observable" out of the expression tree then subscribe to its event?

The code above is not mine, it come from an example recent example from Ayende, here is the like to the full source code if anyone want to take a look of how the Fact class is being used http://github.com/ayende/Effectus


回答1:


Basically, the object you need in this case is stored in expression.Body.Expression. You will need to compile and execute an expression tree to get it. Also, you will probably need to check whether the type really implements your interface and whether the predicate is what your really are looking for.

Here is a very rough code:

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()();
    //...
}


来源:https://stackoverflow.com/questions/1936852/how-do-i-subscribe-to-an-event-of-an-object-inside-an-expression-tree

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!