Mängel bei der Verwendung dynamischer Typen in C #


14

Ich habe kürzlich mehr über die dynamischen Typen in C # gelernt. Mit einigen Beispielen habe ich verstanden, dass der Code nach dem Kompilieren nicht erneut kompiliert werden muss, sondern direkt ausgeführt werden kann.

Ich halte die Flexibilität, die das Schlüsselwort bietet, um den Datentyp tatsächlich nach Belieben ändern zu können, für einen großen Vorteil .

Frage,

Gibt es bestimmte Mängel, abgesehen von falschen dynamischen Methodenaufrufen, die Laufzeitausnahmen auslösen, die Entwickler kennen müssen, bevor sie mit der Implementierung beginnen.


3
In C # 3 habe ich die Verwendung von objectoder direkte Typumwandlungen immer als Code-Geruch betrachtet. In fast allen Fällen bedeutete dies, dass ich oder eines meiner Teams keine entsprechende Schnittstelle für diese Funktionalität entwickelt hatten. Ich vermute, wenn ich jetzt C # 4 verwenden würde, würde ich auch in Bezug auf die Verwendung von so ziemlich dasselbe empfinden dynamic. Ich könnte den Fall dafür sehen, wenn Sie alles dynamisch machen, aber in diesem Fall könnten Sie genauso gut eine dynamisch geschriebene Sprache an erster Stelle ausgewählt haben. * 8 ')
Mark Booth

@ MarkBooth +1 für die Perspektive. Ist es dann sicher zu sagen, dass die Kernimplementierung mit C # trotz der Einführung dynamischer Typen in 4.0
Karthik Sreenivasan

Wenn Sie dynamicin C # arbeiten, müssen Sie nicht auf IronPython verzichten, wenn Sie nur einen kleinen Teil Ihres Codes dynamisch eingeben müssen. Für einen Ausdrucksauswerter hatte ich großen Erfolg damit dynamic, die Operanden eines Ausdrucks und die Ergebnisse der Auswertung darzustellen.
Ed James

@EdJames - Das klingt nach einer großartigen Verwendung von. Außerdem dynamicwünschte ich, ich hätte bei der Entwicklung mit .Net etwas über IronPython gewusst - es hätte bestimmte Dinge, die wir zu tun versuchten, viel einfacher machen können.
Mark Booth

Antworten:


16

Das Hauptmanko ist, dass Sie eine der Haupteigenschaften (nicht unbedingt Vorteile) von C # wegwerfen - dass es statisch typisiert ist (und größtenteils typensicher ist).

Das Problem bei der dynamischen Typisierung besteht darin, dass häufig Fehler ausgeblendet werden, die ansonsten beim Kompilieren aufgedeckt würden. Ein solcher Fehler tritt dann nur zur Laufzeit auf, was es natürlich viel schwieriger macht, ihn zu erkennen.

Es gibt nur wenige IMO-Gründe für die Verwendung der dynamischen Typisierung in C #. Der Hauptgrund ist die Zusammenarbeit mit dynamisch typisierten Sprachen (AFAIK ist der Grund, warum die dynamische Typisierung ursprünglich eingeführt wurde).

Wenn Sie vollständig dynamisch programmieren möchten, sollten Sie sich eine Sprache ansehen, die so konzipiert ist, dass sie dynamisch ist, und nicht C #, um dynamisch zu sein. Sie können beispielsweise IronPython verwenden, wenn Sie .NET-Bibliotheken verwenden möchten


+1 für IronPython. Dies kann langfristig zu Wartungsproblemen führen.
Karthik Sreenivasan

6
Die große Sache, dynamicdie Sie gibt, ist die Fähigkeit, ein Objekt ohne jede Art von Reflexionshack auf seinen tatsächlichen Typ hochzuwerfen. Zum Beispiel, wenn Base foo = new Derived();und es gab zwei überladene Methoden Moo(Base x)und Moo(Derived x), dann Moo(foo)ruft auf Moo(Base x), aber Moo((dynamic)foo)ruft auf Moo(Derived x). Dies führt zu einer sehr eleganten Implementierung des Besuchermusters, zum Beispiel: code.logos.com/blog/2010/03/…, und ist im Allgemeinen eine sehr leistungsfähige Technik.

@TheMouthofaCow Schön, es gibt sicherlich auch ein paar andere "legitime" Verwendungszwecke für Dynamik, allerdings gibt es nur wenige dazwischen (und Sie müssen auf jeden Fall wissen, was Sie tun, bevor Sie so etwas versuchen).
Matěj Zábský

@TheMouthofaCow Ein relativ neues Designmuster (The Visitor Pattern) zur Kenntnis zu nehmen. Vielen Dank.
Karthik Sreenivasan

1
Ja, es ist ziemlich cool. Ich habe es letzte Woche unabhängig erfunden, und es war schön zu sehen, dass es eine akzeptierte Idee ist, die in das C # -Arsenal aufgenommen wurde.

9

Ich bin mir nicht sicher, welche Art von Mängeln Sie suchen, aber wenn Sie wissen möchten, welche Funktionen mit statischer Eingabe funktionieren, aber nicht mit dynamic, gibt es einige:

  1. Erweiterungsmethoden funktionieren nicht. Dies ist wahrscheinlich der größte. Wenn Sie haben dynamic collection, können Sie keinen Code wie verwenden collection.Distinct(). Das liegt daran, dass die verfügbaren Erweiterungsmethoden von Namespaces abhängen usingund der DLR keine Möglichkeit hat, diese zu ermitteln.

    Als Abhilfe können Sie entweder die Methode aufrufen , als ob es normale statische Methode war: Enumerable.Distinct(collection). Oder Sie können den Typ der Sammlung in etwas ändern IEnumerable<dynamic>.

  2. foreacherfordert IEnumerable. In normalem C # foreachist musterbasiert. Das heißt, es ist keine bestimmte Schnittstelle erforderlich, nur eine GetEnumerator()Methode, die ein geeignetes Objekt zurückgibt. Wenn Sie foreachauf verwenden dynamic, ist die Implementierung von IEnumerableerforderlich. Aber da der Grund für dieses Verhalten darin besteht, dass C # 1.0 keine Generika hatte, ist dieses "Manko" so ziemlich irrelevant.


+1 für Erweiterungsmethode. Gilt dies auch für andere LINQ-Abfrageoperatoren wie GroupBy ()?
Karthik Sreenivasan

2
@ Karthik: Ja, das tut es. Ich denke, dass Erweiterungsmethoden syntaktische Zucker kompilieren, daher die Tatsache, dass sie nicht aufgelöst werden.

@TheMouthofaCow +1 - Danke für die Klarstellung.
Karthik Sreenivasan

1
Ich bin mit den Erweiterungsmethoden einverstanden, dh wie die Dynamik Erweiterungsmethoden zur Laufzeit nicht ermitteln kann, aber ich konnte der von Ihnen erklärten dynamischen Sammlung nicht folgen.
Karthik Sreenivasan

7

Das Problem mit dynamischen Typen (keine als dynamisch deklarierten Variablen) in .net besteht darin, dass statischen Typen nicht viele Funktionen zur Verfügung stehen.

  • Es gibt keine Reflexion (Sie können über Mitglieder iterieren, aber nicht viel anderes)
  • Keine Metadaten (da geht Ihre Validierung in Dynamic Data Sites / MVC)
  • Absolut keine Überprüfung zur Kompilierungszeit (Rechtschreibfehler werden nicht abgefangen)
  • da dies ein mächtiges Feature ist, neigen Noobs dazu, es zu missbrauchen / missbrauchen / misszuverstehen
  • Code, der mit dynamischen Typen geschrieben wurde, ist in der Regel schwer zu warten und verdammt schwer umzugestalten
  • Aufgrund der Eingabe von Enten und anderer Funktionen können Gurus Code schreiben, der für andere nicht lesbar ist

Schreiben Sie also keinen Code mit dynamischen Typen, es sei denn, Sie wissen, was Sie tun.


6

Da dynamices sich nur um ein gekennzeichnetes objectFeld handelt, werden Werttypen angezeigt.

Dies kann Auswirkungen auf die Leistung haben, aber da ich sowieso die statische Eingabe in leistungskritischen Code verwenden würde, ist dies in der Praxis wahrscheinlich kein Problem.

Dieses Boxen stört auch veränderbare Werttypen. Wenn Sie sie mit ändern dynamic, ändern Sie nur die Boxed Copy. Da Sie jedoch in erster Linie keine veränderlichen Werttypen verwenden sollten, ist dies auch kein großes Problem.


+1 Ich stimme definitiv zu. Die statische Typisierung ist der beste Ansatz für leistungskritischen Code.
Karthik Sreenivasan
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.