Ich bin ziemlich zufrieden mit meinem Verständnis des .NET-Ereignismodells. Ich denke, ich könnte eine kleine Nuance des Systems missverstehen.
Als ich anfing, Events in meine Klassen aufzunehmen, habe ich die Standardmethode wie folgt verwendet:
public event EventHandler<MyEventArgs> MyEvent;
Dies bedeutete, dass alles, was das Ereignis abonniert, eine Methode wie die folgende benötigt:
void HandleThatEvent(object sender, MyEventArgs args){...}
Was nett ist, aber ich fand, dass ich mich selten um den Absender kümmern würde, so dass viele Methodensignaturen aufgebläht wurden.
Also habe ich meine eigenen Delegiertentypen deklariert
public delegate void MyEventHandler(SomeClass argument);
Was die Unordnung einschränkt, mir aber ein kleines Problem beim Schreiben von Handlern hinterlässt:
eventImplmentor.MyEvent += HandleThatEvent;
.
.
.
void HandleThatEvent(/*oh, um, what arguments does it take? Intellisense isn't telling me*/)
Also müsste ich zur Erklärung des Delegierten zurückkehren und nachsehen und sie dann zurückschreiben oder kompilieren und warten, bis sie mir mitgeteilt werden.
Also verwende ich stattdessen einfach eine Vorlage Action
, Action<T>
oder welche auch immer passt.
public event Action<SomeClass> MyEvent;
Damit ich über das Ereignis schweben und erfahren kann, welche Parameter es erwartet.
Meine Frage nach all dem: Gibt es eine bewährte Methode zum Deklarieren von Ereignissen in C #? Soll ich auf den EventHandler<T>
Weg zurückgehen, oder ist das Action<T>
akzeptabel?
Antworten:
Für eine einfache interne Ereignisbehandlung gibt es solche, die einfach
Action
oder verwendenAction<T>
, wie Sie es vorschlagen. Ich neige dazu, das Standardmuster, einschließlich des Absenders, auch für interne Ereignisse zu verwenden, da Sie nie wissen, wann Sie später eine Klasse oder ein Ereignis verfügbar machen möchten, und ich möchte nicht die Strafe, die Ereignismethode nur umgestalten zu müssen, um dies zu erreichen es öffentlich.Ich stimme Ihnen zu, dass die Signatur für die Ereignisbehandlung etwas schwerer ist, als es für einfache Szenarien sein sollte, aber sie ist gut für die inkrementelle Migration ausgelegt, da im Laufe der Zeit zusätzliche Ereignisargumente erforderlich werden könnten. Insgesamt würde ich mich an das Standardmuster halten, zumal Sie, wie Sie bereits bemerkt haben, nur dann eine ordnungsgemäße IntelliSense-Unterstützung erhalten, wenn Sie dies tun.
Für das, was es wert ist, habe ich mir etwas Zeit genommen und mir ein anderes Ereignisbehandlungsmuster ausgedacht : Ereignissignatur in .NET - Verwenden eines stark typisierten "Absenders"? . Das Ziel hier war nicht, den Absender zu entfernen, sondern ihn generisch als stark
TSender
anstatt schwach als getippt zu kennzeichnenSystem.Object
. Es funktioniert sehr gut; Wenn Sie dies tun, geht jedoch die IntelliSense-Unterstützung verloren, sodass ein unglücklicher Kompromiss besteht.Insgesamt würde ich mich an das Standardmuster halten, aber es ist interessant, über potenziell bessere Möglichkeiten nachzudenken, um dies zu tun.
quelle