2010-10-15 2 views
25

den Code Betrachtet man unter:Invocation einer polymorphen feldartigen Ereignis

public class TableMain { 
    public virtual event Action UpdateFilter; 
    .... 
} 

public class TableSub : TableMain { 
    public override event Action UpdateFilter; 

    public void UpdateQuery() { 
     ..... 
     if (UpdateFilter!=null) { 
       UpdateFilter(); // Invocation of polymorphic field-like event??? 
     } 
    } 
} 

In diesem Code ReSharper zeigt die Warnung „Aufruf von polymorphen feldartigen Ereignis“.

Meine Frage ist: Was bedeutet es eigentlich? Und ist es eine Warnung für eine schlechte Programmierpraxis? Ist es auch eine schlechte Übung, ein Ereignis polymorph zu benennen? (Wissen, dass ein Ereignis nur von der Klasse ausgelöst werden kann, die es deklariert hat.)

Antwort

41

Nun, Sie haben tatsächlich zwei feldähnliche Ereignisse hier. Ihre Außerkraftsetzung überschreibt den Hinzufügen/Entfernen-Teil, aber Sie haben zwei Felder - eins in TableMain und eins in TableSub. Nur der eine in TableSub wird niemals ungleich null sein, es sei denn, der Wert wird explizit in TableMain ... festgelegt. Wenn also TableMain jemals versucht, das Ereignis selbst auszulösen, ruft es nicht den gleichen Satz von Handlern auf wie in TableSub. Im Grunde wird es sich seltsam verhalten.

Der richtige Ansatz ist eine geschützte Methode in TableMain, um der Veranstaltung zu ermöglichen, von den Unterklassen erhöht werden:

protected void OnUpdateFilter() 
{ 
    Action handler = UpdateFilter; 
    if (handler != null) 
    { 
     handler(); 
    } 
} 

Dann wird das Ereignis nicht-virtuelle machen, und die Überschreibung in TableSub entfernen.

Beachten Sie, dass Ihre Ereignissignatur nicht mit der normalen Konvention für Ereignisse übereinstimmt - ein Grund, EventHandler nicht zu verwenden?

+0

Das klingt für mich nach einer großen potenziellen Fehlerquelle, weil es höchstwahrscheinlich nicht das ist, was man erwarten würde, wenn man solchen Code schreibt. Hatte nie zuvor über diesen spezifischen Aspekt nachzudenken. Weißt du, warum virtuelle Ereignisse syntaktisch überhaupt erlaubt sind? –

+1

@ John. Betreffend --- "Beachten Sie, dass Ihre Ereignissignatur nicht mit der normalen Konvention für Ereignisse übereinstimmt - ein Grund, EventHandler nicht zu verwenden?" Ich benutze gerade den bestehenden "Action" -Delegaten, da ich in diesem Fall keine Argumente (object, eventargs) in den Abonnenten dieser Veranstaltung brauche. Ist das (wieder) eine schlechte Programmierpraxis? Ist es eine bessere Idee, einen separaten (leeren) Delegaten für diesen Fall zu erstellen? –

+1

@Thomas: Es gibt Möglichkeiten, wie Sie sie sinnvoll nutzen könnten - zum Beispiel könnten Sie jedes Abonnement protokollieren und es dann an die Basisimplementierung übergeben. Außerdem müssen Sie in der Lage sein, abstrakte Ereignisse effektiv zu nutzen, um sie in Interfaces einfügen zu können. –

Verwandte Themen