Ich habe vor kurzem gelernt, C# -Erweiterungsmethoden zu verwenden, um das Aufrufen von Ereignissen zu vereinfachen, und ich benutze sie immer häufiger. Ich habe vor kurzem ein seltsames Problem gefunden, das ich nicht verstehe, und ich habe mich gefragt, ob jemand es erklären könnte.Ereignisse mit C# -Erweiterungsmethoden behandeln
Das Problem tritt auf, wenn Sie versuchen, eine Eventhandler-Erweiterungsmethode als Ereignishandler eines anderen Ereignisses festzulegen. Hier ist ein Beispiel dafür, was ich tue:
public static class EventHandlerExtensions
{
public static void Raise<TEventArgs>(
this EventHandler<TEventArgs> eventHandler,
object sender, TEventArgs args) where TEventArgs:EventArgs
{
if (eventHandler != null)
{
eventHandler(sender, args);
}
}
}
public class Test
{
private event EventHandler<EventArgs> EventA;
private event EventHandler<EventArgs> EventB;
public Test()
{
Console.WriteLine("::Start");
EventB += EventA.Raise;
EventA += (s, a) => Console.WriteLine("Event A raised");
EventB.Raise(this, EventArgs.Empty);
Console.WriteLine("::End");
}
}
In diesem Beispiel sollte Eventa als Ergebnis ausgelöst werden EventB ausgelöst wird. Wenn ich diesen Code ausführe, wird EventB jedoch ausgelöst, aber die Erweiterungsmethode für A findet keine Listener dafür.
Wenn ich den Auftrag um zu ändern, funktioniert alles einwandfrei:
Console.WriteLine("::Start");
EventA += (s, a) => Console.WriteLine("Event A raised");
EventB += EventA.Raise;
EventB.Raise(this, EventArgs.Empty);
Console.WriteLine("::End");
Auch EventA.Raise von einem Lambda-Aufruf funktioniert:
Console.WriteLine("::Start");
EventB += (s, a) => EventA.Raise(s, a);
EventA += (s, a) => Console.WriteLine("Event A raised");
EventB.Raise(this, EventArgs.Empty);
Console.WriteLine("::End");
Dies ist nur ein einfaches Beispiel, aber ich Ich versuche, eine Klasse zu erstellen, die Ereignisse von Ereignisquellen, die ihr hinzugefügt wurden, auf die sauberste Weise neu versenden kann. Ich möchte keine benannten Methoden nur für das Redispatching der gleichen Ereignisse erstellen, und ich möchte lieber keine Listen von Lambda-Funktionen speichern, die ich später aus den Event-Handlern aushängen kann. Meistens bin ich nur neugierig, warum das passiert?
Irgendwelche Ideen?
Das könnte wirklich schlimm werden, wenn Sie viele Event-Handler haben, die Sie abonnieren. Gute Frage, obwohl !!! :) – IAbstract
Wenn ich deinen Code in VS2010 aufschreibe, tippe 'EventA.R' direkt nach' Console.WriteLine ("Start"); 'zeigt nicht die Erweiterungsmethode in intelliSense an. Es tut wenn ich es kurz vor 'Console.WriteLine (" End ");'. Seltsam. – Guillaume