Deficiencias en el uso de tipos dinámicos en C #


14

Recientemente he estado estudiando más sobre los tipos dinámicos en C #. Con algunos ejemplos que entendí una vez que se compila el código, no es necesario volver a compilarlo, pero se puede ejecutar directamente.

Creo que la flexibilidad que brinda la palabra clave para poder cambiar el tipo de datos a voluntad es una gran ventaja .

Pregunta,

¿Hay alguna deficiencia específica aparte de las llamadas incorrectas a métodos dinámicos que arrojan excepciones de tiempo de ejecución que los desarrolladores deben conocer antes de comenzar la implementación?


3
En C # 3, siempre consideré que el uso de objectmoldes de tipo directo es un olor a código. En casi todos los casos, significaba que yo o uno de mi equipo no había diseñado una interfaz adecuada para esa funcionalidad. Supongo que si estuviera usando C # 4 ahora, me sentiría casi de la misma manera sobre el uso de dynamic. Podría ver el caso si lo hace todo dinámico, pero en ese caso también podría haber seleccionado un lenguaje de escritura dinámico en primer lugar. * 8 ')
Mark Booth

@MarkBooth +1 para la perspectiva. ¿Es seguro decir que la implementación principal que usa C # seguirá siendo fuertemente tipada a pesar de introducir tipos dinámicos en 4.0
Karthik Sreenivasan

El uso dynamicen C # significa que no tiene que abandonar IronPython si todo lo que necesita es escribir algo dinámico para una pequeña parte de su código. Para un evaluador de expresiones, he tenido un gran éxito dynamical representar los operandos de una expresión y los resultados de la evaluación.
Ed James

@EdJames: eso suena como un gran uso de dynamic, además desearía haber sabido sobre IronPython cuando estaba desarrollando con .Net, podría haber hecho que ciertas cosas que estábamos tratando de hacer fueran mucho más fáciles.
Mark Booth

Respuestas:


16

La principal desventaja es que descarta una de las principales propiedades (no necesariamente ventajas) de C #: que está estáticamente tipado (y para la mayoría de los tipos es seguro).

El problema con la escritura dinámica es que a menudo oculta errores que de otro modo se revelarían durante la compilación. Tal error solo se manifiesta en tiempo de ejecución, lo que por supuesto hace que sea mucho más difícil de detectar.

Hay muy pocas razones de la OMI para usar la escritura dinámica en C #, la principal es la colaboración con lenguajes escritos dinámicamente (que es AFAIK, la razón por la que la dinámica se introdujo en primer lugar).

Si desea hacer una programación totalmente tipada dinámicamente, debe buscar algún lenguaje que esté diseñado para ser dinámico, no piratear C # para que sea dinámico. Puede usar, por ejemplo, IronPython si desea usar bibliotecas .Net


+1 para IronPython. Esto significa que esto podría conducir a problemas de mantenimiento a largo plazo.
Karthik Sreenivasan

66
La gran cosa que dynamicte brinda es la capacidad de lanzar un objeto a su tipo real sin ningún tipo de truco de reflexión. Por ejemplo, si Base foo = new Derived();hubo dos métodos sobrecargados Moo(Base x)y Moo(Derived x), luego , Moo(foo)llamadas Moo(Base x), pero Moo((dynamic)foo)llamadas Moo(Derived x). Esto lleva a una implementación muy elegante del patrón Visitor, por ejemplo: code.logos.com/blog/2010/03/… y es, en general, una técnica muy poderosa.

@TheMouthofaCow Nice, seguramente también hay algunos otros usos "legítimos" para la dinámica, sin embargo, estos son pocos y distantes entre sí (y definitivamente tienes que saber lo que estás haciendo antes de intentar algo como esto).
Matěj Zábský

@TheMouthofaCow Un patrón de diseño relativamente nuevo (The Visitor Pattern) para tener en cuenta. Gracias.
Karthik Sreenivasan

1
Sí, es genial. Se me ocurrió de forma independiente la semana pasada, así que fue agradable ver que es una idea aceptada que se ha adoptado en el arsenal de C #.

9

No estoy seguro de qué tipo de deficiencias está buscando, pero si desea conocer las funciones que funcionan con la escritura estática, pero no con ellas dynamic, hay algunas:

  1. Los métodos de extensiones no funcionan. Este es probablemente el más grande. Si es así dynamic collection, no puede usar código como collection.Distinct(). Esto se debe a que los métodos de extensión disponibles dependen de los espacios de nombres usingy el DLR no tiene forma de conocerlos.

    Como solución, puede invocar el método de como si fuera normal, método estático: Enumerable.Distinct(collection). O puede cambiar el tipo de colección a algo así IEnumerable<dynamic>.

  2. foreachrequiere IEnumerable. En C # normal, foreachse basa en patrones. Es decir, no requiere ninguna interfaz específica, solo un GetEnumerator()método que devuelve un objeto adecuado. Si se utiliza foreachen dynamicla implementación de IEnumerablese requiere. Pero dado que la razón de este comportamiento es que C # 1.0 no tenía genéricos, esta "deficiencia" es prácticamente irrelevante.


+1 para el método de extensiones. ¿Esto también se aplica a otros operadores de consulta LINQ como GroupBy ()?
Karthik Sreenivasan

2
@Karthik: Sí, lo hace. Creo que los métodos de extensión son azúcar sintáctica en tiempo de compilación, de ahí el hecho de que no se resuelven.

@TheMouthofaCow +1 - Gracias por la aclaración.
Karthik Sreenivasan

1
Estoy de acuerdo con los métodos de extensión, es decir, cómo la dinámica no puede descubrir los métodos de extensión en tiempo de ejecución, pero no pude seguir la colección dinámica que ha explicado.
Karthik Sreenivasan

7

El problema con los tipos dinámicos (no las variables declaradas como dinámicas) en .net es que no tienen mucha funcionalidad disponible para los tipos estáticos.

  • no hay reflexión (puedes iterar sobre los miembros pero no mucho más)
  • sin metadatos (ahí va su validación en sitios de datos dinámicos / mvc)
  • absolutamente ninguna comprobación en tiempo de compilación (no se detectarán errores ortográficos)
  • Dado que esta es una característica poderosa, los novatos pueden tender a abusar / mal uso / malentendido
  • el código escrito con tipos dinámicos tiende a ser difícil de mantener y muy difícil de refactorizar
  • debido al tipeo de patos y otras características, los gurús pueden escribir código que nadie más puede leer

Por lo tanto, no escriba código con tipos dinámicos a menos que sepa lo que está haciendo.


6

Dado que dynamices solo un marcado object, recuadra los tipos de valor.

Esto puede tener implicaciones de rendimiento, pero dado que de todos modos usaría la escritura estática en el código crítico de rendimiento, probablemente eso no sea un problema en la práctica.

Este boxeo también interfiere con los tipos de valores mutables. Si los modifica con dynamic, solo modificará la copia en recuadro. Pero como no debe usar tipos de valores mutables en primer lugar, tampoco es un gran problema.


+1 Definitivamente estoy de acuerdo. La escritura estática sería el mejor enfoque para el código crítico de rendimiento.
Karthik Sreenivasan
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.