Verwenden von 'dynamic' in C # zum Implementieren des Besuchermusters

8

Ich habe eine Anwendung, bei der ich eine Operation an einer Reihe von Elementen durchführe und die genaue Art der Operation hängt von der Art des Elements ab, auf dem gearbeitet wird. Aus Gründen der Kapselung ist es nicht sinnvoll, dass das Element die Operation implementiert; Dies bedeutet, dass es keine virtuelle Methode für den Elementtyp sein kann und daher funktioniert "Standard" -Polymorphismus nicht. Ich habe eine vorherige Frage bezogen zu diesem und wurde informiert, dass dies als das Besuchermuster bekannt war.

Ich hatte das zuvor immer mit einer if/elseif dispatcher-Methode basierend auf dem Objekttyp implementiert und dann eine entsprechende Implementierung aufgerufen. In letzter Zeit habe ich jedoch festgestellt, dass dasselbe mit dem Schlüsselwort dynamic wie folgt erreicht werden kann:

%Vor%

Ein ähnliches Muster könnte für andere Operationen parallel zur Klassenstruktur verwendet werden, wie das Erstellen von Ansichtsmodellen für jedes Element von _definition.Steps . Der Gedanke ist, dass der Compiler im Grunde genommen diese in die gleiche if/elseif -Logik umwandelt, die ich vorher geschrieben habe, was mir den Aufwand erspart. Also, ein paar Fragen:

  1. Gibt es irgendwelche Probleme mit der dynamischen Verteilung, die ich nicht in Betracht gezogen habe? Ich glaube, das entspricht einer Reihe von if (x is TypeA) Do((TypeA)x) else... , aber ich könnte falsch liegen.

  2. Ist das tatsächlich sauberer und einfacher zu verstehen als eine lange if/elseif Methode?

Dan Bryant 01.05.2013, 20:58
quelle

2 Antworten

9
  

Gibt es irgendwelche Probleme mit der dynamischen Verteilung, die ich nicht berücksichtigt habe? Ich glaube, das ist äquivalent zu einer Reihe von if (x ist TypA) Do ((TypA) x) sonst ..., aber ich könnte falsch liegen.

Das Hauptproblem wäre, wenn ein Typ mehr als eine Schnittstelle in Ihrem Besuchermuster implementiert - der Compiler wird wahrscheinlich den gewünschten auswählen, aber es ist möglicherweise nicht die selbe Wahl, die Sie treffen würden, wenn Sie if (x is TypeA) / verwenden else if (x is TypeB) logic, da Sie die Reihenfolge der Prüfungen steuern würden.

  

Ist das tatsächlich sauberer und leichter zu verstehen als eine lange if / elseif-Methode?

Ich persönlich denke schon. Dies bietet eine sehr saubere, recht anständige Ausführung, die vom Laufzeittyp bestimmt wird und "einfach funktioniert". Schwer zu übertreffen einfacher, kurzer, sauberer Code. Stellen Sie sicher, dass Sie (möglicherweise) den Fall behandeln, in dem Sie einen Laufzeitfehler vom falschen Typ bekommen, der übergeben wird.

    
Reed Copsey 01.05.2013, 21:01
quelle
1

Ja, ich habe über diesen Ansatz nachgedacht, mich aber für einen eher traditionellen Ansatz dagegen entschieden. Ich leite jeden Besucher von einer Schnittstelle ab, die Besuchsmethoden für jeden Typ hat, für den ich die Operation implementieren möchte.

Wenn Sie eine Reihe von verschiedenen Vorgängen haben, die Sie als Besucher implementieren möchten, z. Speichern und Laden von Vorgängen. Möglicherweise möchten Sie in Zukunft weitere hinzufügen. Mit dem dynamischen Ansatz erhalten Sie keine Kompilierungsfehler, wenn Sie vergessen, die Operation für einen der Typen zu implementieren, die Sie behandeln müssen. Sie werden nur herausfinden, wenn das Programm abstürzt und zur Laufzeit brennt.

Ich möchte zur Kompilierzeit sicher sein, dass eine Operation für alle möglichen Typen implementiert wurde.

    
Scott Langham 07.02.2017 11:23
quelle

Tags und Links