views:

43

answers:

1

How to make lambda like this

Action<EventHandler<TEventArgs>> adder = vs => GenericEvent += vs

using expression trees. This code doesn't work:

Expression<Func<EventHandler<TEventArgs>>> handler = () => GenericEvent;
var vs = Expression.Parameter(typeof(EventHandler<TEventArgs>), "vs");    
var adder = Expression.Lambda<Action<EventHandler<TEventArgs>>>(
            Expression.AddAssign(handler.Body, vs), vs).Compile();

Error message:

The binary operator AddAssign is not defined for the types 'System.EventHandler1[ConsoleApplication.Program+SomeEventArgs]' and 'System.EventHandler1[ConsoleApplication.Program+SomeEventArgs]'.

+1  A: 

Well to start with you need to be very clear in your mind the difference between events and delegate fields.

We can't tell what GenericEvent is in the first case, but if it really does refer to an event, that will be calling add_GenericEvent or whatever the appropriate underlying metadata gives. Compare that with the second case, where you really want to call Delegate.Combine, cast the result back to EventHandler<TEventArgs> and then assign it back to GenericEvent. In both cases the C# compiler is using syntactic sugar really - and you need to unpick that sugar to create the relevant expression tree.

Jon Skeet