is it possible to generate an eventhandler while running?
I want to do something like that:
public bool addCallback(string name, Delegate Callback)
{
EventInfo ei = DataProxy.GetType().GetEvent(name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
if (ei == null)
return false;
ei.AddEventHandler(DataProxy, Callback);
//now I want to add an Eventhandler, which removes the Callback and this new Eventhandler itsself
return true;
}
(I am not 100% sure I understand what you are going to hook your generated event handler to from the example, but here’s the easiest way I know of for creating an event handler)
Depends on your platform and trust level. The most flexible way of doing it is to use
Emitto generate the method (see here).However, I found a relatively easy to use and good alternative to be generated Linq expressions (here’s the namespace help).
The idea is fairly simple:
Use the various Expression-derived classes you can see in the namespace to define what your callback is doing. In this case, you want to generate something that calls
.RemoveEventHandler(I am guessing) on theeiinstance (specifically, you will use the ConstantExpression to create a ref to youreivariable and to your Callback parameter and a MethodCallExpression to create a call to theRemoveDataHandlermethod).Once you create the expression that does what you need, you need to create a delegate (Lambda) out of it (see here)
Almost done. You still need to compile the lambda, which you do by calling
.Compileon the object you got from the previous step (see here)Edit: This is a Windows console example of a dynamically generated delegate that removes itself. Note that WP7 Linq expression support is more limited than .NET 4.0 and so you will need to adjust it (make helper methods that will do some of the work and call them from the expression instead of what I did).
Edit2: BTW: The mechanism by which the lambda can remove itself, is to create another lambda that returns a local variable that is of that type. After creating the lambda, save it to the local variable and run the code (I am not sure if this would have worked without the secondary lambda)
Edit3: No – you have to use the delegate trick, otherwise, the constant gets “frozen” and will not update as you would want it to. So the code as is works.