Comment passer la valeur lors de la souscription à l'événement et l'obtenir lorsque l'événement est déclenché (problèmes d'utilisation DynamicMethod)
-
25-09-2019 - |
Question
La tâche est de créer des gestionnaires d'événements dans l'exécution. J'ai besoin d'une méthode à appeler avec différentes valeurs de paramètres pour différents événements. Les événements et leur nombre ne sont connus dans l'exécution. Donc, je suis en train de générer des méthodes dynamiques, dont chacun sera affecté à un événement, mais en général ils sont tous juste passer une certaine valeur à une méthode d'instance et l'appeler.
Il serait grand si quelque chose de semblable pourrait se faire de la façon plus facile. Je veux dire en passant une certaine valeur à l'étape abonnement et ensuite l'obtenir lorsque l'événement est déclenché.
est ce que je suis en train de faire maintenant:
public class EventSource
{
public event EventHandler eventOne;
public event EventHandler eventTwO;
public event EventHandler eventThree;
}
public class EventListener
{
SubscribeForEvents()
{
BindingFlags flags =
BindingFlags.IgnoreCase |
BindingFlags.Public |
BindingFlags.Instance;
// Suppose we've already got EventInfo
// and target source somewhere
// so we can do eventInfo.AddEventHandler(target, delegate)
// Now we need a delegate.
int value = 42;
Type tDelegate = eventInfo.EventHandlerType;
// http://msdn.microsoft.com/en-us/library/ms228976(VS.95).aspx
Type returnType = GetDelegateReturnType(tDelegate);
DynamicMethod listener = new DynamicMethod("", null,
GetDelegateParameterTypes(tDelegate), this.GetType());
/////////
Type[] callParameters = { typeof(int) };
MethodInfo method = this.GetType().GetMethod("ToCallFromDelegate", flags);
ILGenerator generator = listener.GetILGenerator();
// No success in this mess. What's wrong?
generator.Emit(OpCodes.Ldc_I4, value);
generator.Emit(OpCodes.Call, method);
generator.Emit(OpCodes.Pop);
generator.Emit(OpCodes.Ret);
/////////////
Delegate delegate = listener.CreateDelegate(tDelegate);
eventInfo.AddEventHandler(target, delegate);
// When triggered, there is InvalidProgramException
}
void ToCallFromDelegate(int value)
{
doSomething();
}
}
La solution
lambdas comme gestionnaires d'événements;)