2011-01-10 14 views
33

Estoy planeando usar la palabra clave dinámica para mi nuevo proyecto. Pero antes de intervenir, me gustaría saber acerca de los pros y los contras del uso de la palabra clave dinámica sobre Reflection.Dynamic Lang. Runtime vs Reflection

Tras donde los profesionales, que pude encontrar en relación con dinámica de palabras clave:

  • legible código \ Mantenible.
  • Menos líneas de código.

Mientras que los aspectos negativos asociados con el uso de palabras clave dinámica, que vinieron a escuchar era como:

  • afecta al rendimiento de la aplicación.
  • La palabra clave dinámica es internamente un contenedor de Reflection.
  • La tipificación dinámica podría convertirse en caldo de cultivo para errores difíciles de encontrar.
  • Afecta la interoperabilidad con versiones anteriores de .NET.

Por favor ayúdenme si los pros y los contras que encontré son razonables o no?

+0

¿Necesita hacer una reflexión * privada *? –

+0

No, no necesito una reflexión privada. Cualquier método que necesite llamar es siempre público. – AbrahamJP

Respuesta

23

legible código Mantenible \

cierto en mi experence.

Menos líneas de código.

No significativamente, pero ayudará.

Afecta el rendimiento de la aplicación.

Very slightly.Pero ni siquiera cerca de la forma en que lo hace la reflexión.

La palabra clave dinámica es internamente un contenedor de Reflection.

Completamente falso. La palabra clave dinámica aprovecha el Dynamic Library Runtime.

[Editar: corrección según comentario más abajo]

Parecería que el tiempo de ejecución de lenguaje dinámico hace uso Reflexión y las mejoras de rendimiento son solamente debido a las técnicas cacheing.

La tipificación dinámica podría convertirse en caldo de cultivo para errores difíciles de encontrar.

Esto puede ser verdad; depende de cómo escribes tu código. Está eliminando efectivamente la verificación del compilador de su código. Si la cobertura de su prueba es buena, probablemente esto no importará; si no, entonces sospecho que se encontrará con problemas.

Afecta la interoperabilidad con versiones anteriores de .NET

No es cierto. Quiero decir que no podrás compilar tu código con versiones anteriores, pero si quieres hacerlo, debes usar las versiones anteriores como base y compilarlas en lugar de al revés. Pero si desea utilizar una biblioteca .NET 2, entonces no debería encontrarse con demasiados problemas, siempre y cuando incluya la declaración en app.config/web.config.

Una gran ventaja que te falta es la interoperabilidad mejorada con los componentes COM/ATL.

+0

Así que puedo tomar su palabra de que, no habrá diferencias de rendimiento notables mediante el uso de reflexión dinámica (DLR). Gracias por señalar la interoperabilidad mejorada en COM \ ATL. – AbrahamJP

+1

@AbrahamJP: usar dynamic es más rápido que utilizar la reflexión, especialmente si se llama repetidamente a un método (debido a la caché). – pdr

+21

Re "Completamente falso. La palabra clave dinámica aprovecha la Biblioteca dinámica de ejecución". ¿Cómo crees exactamente que lo hace DLR? ¿Qué magia tiene a su disposición por lo que puede hacer análisis de tipo de tiempo de ejecución * sin reflexión *? El DLR no tiene magia; usa Reflection cuando necesita que le guste cualquier otro código. Es muy inteligente sobre el almacenamiento en caché del resultado, pero créanme, utiliza la reflexión. –

4

En la mayoría de los casos, el uso de la palabra clave dinámica no dará como resultado un código significativamente más corto. En algunos casos lo hará; eso depende del proveedor y, como tal, es una distinción importante. Probablemente nunca deba usar la palabra clave dinámica para acceder a objetos CLR simples; el beneficio allí es muy pequeño.

La palabra clave dinámica socava las herramientas de refactorización automáticas y hace que las pruebas de unidad de cobertura alta sean más importantes; después de todo, el compilador no revisa mucho de nada cuando lo usa. Eso no es un problema cuando interopera con una API muy estable o con un tipado dinámico inherente, pero es particularmente desagradable si usa la palabra clave dinámica para acceder a una biblioteca cuya API podría cambiar en el futuro (como cualquier código que usted escriba))

Utilice la palabra clave con moderación, cuando tenga sentido, y asegúrese de que dicho código tenga amplias pruebas de unidad. No lo use donde no lo necesite o cuando la inferencia de tipo (por ejemplo, var) pueda hacer lo mismo.

Editar: Usted menciona a continuación que usted está haciendo esto para los plug-ins. El Managed Extensibility Framework se diseñó con esto en mente; puede ser una mejor opción que la palabra clave dynamic y la reflexión.

+1

@Eamon: Como mencioné, no estoy usando la palabra clave dinámica para acceder a los objetos CLR simples, sino la aplicación que mencioné, proporciona un modelo de complemento para manejar nuevas funcionalidades, debido a que esta reflexión se usa ampliamente. Para que este módulo sea eficaz y fácil de mantener, me confundí sobre si elegir Reflection o Dynamic keyword. La principal preocupación para mí es el rendimiento. – AbrahamJP

+2

@AbrahamJP ¿Su modelo de complemento es compatible a través de interfaces o por convención? Si es compatible con interfaces, entonces se necesita usar poca reflexión de todos modos. Los complementos –

+0

no deben requerir una escritura dinámica. Si hay un problema de rendimiento realmente depende de lo que esté haciendo (millones de llamadas pequeñas frente a una o dos grandes), pero a priori no esperaba * que el rendimiento fuera un problema. –

2

Si utiliza dinámicamente específicamente para hacer reflejos, su única preocupación es la compatibilidad con versiones anteriores. De lo contrario, gana sobre la reflexión porque es más legible y más corto. En cualquier caso, perderá una fuerte capacidad de tipeo y (algunos) resultados del mismo uso de la reflexión.

1

El modo de ver todas sus desventajas para el uso dinámico, excepto la interoperabilidad con las versiones anteriores de .NET también están presentes cuando se utiliza Reflexión:

afecta al rendimiento de la aplicación

Si bien no afecta al rendimiento , también lo hace usando Reflection. Por lo que recuerdo, el DLR usa más o menos Reflection la primera vez que accede a un método/propiedad de su objeto dinámico para un tipo dado y almacena en caché el par de tipo/acceso objetivo para que el acceso posterior sea solo una búsqueda en el caché que lo hace más rápido entonces Reflexión

dinámica de palabras clave es internamente un envoltorio de Reflexión

Incluso si era verdad (véase más arriba), ¿Cómo sería un punto negativo? Si se ajusta o no Reflexión no debe influir en su aplicación en ningún asunto importante.

tipado dinámico podría convertirse en caldo de cultivo para los difíciles de encontrar errores

Si bien esto es cierto, siempre y cuando se utiliza con moderación no debe ser que gran parte de un problema. Además, básicamente lo usas como un reemplazo para la reflexión (es decir, utilizas la dinámica solo durante las breves duraciones posibles cuando quieres acceder a algo mediante la reflexión), el riesgo de tales errores no debería ser significativamente mayor que si usas la reflexión para acceda a sus métodos/propiedades (por supuesto, si hace que todo sea dinámico, puede ser un problema mayor).

Afecta la interoperabilidad con versiones anteriores de .NET

Para que usted tiene que decidir por ti mismo qué parte de una preocupación que es para usted.

90

Ayúdenme si los pros y los contras que encontré son razonables o no?

La preocupación que tengo con sus pros y sus contras es que algunos de ellos no abordan las diferencias entre el uso de la reflexión y el uso dinámico. Esa tipificación dinámica hace que los errores no se capten hasta que el tiempo de ejecución sea cierto para cualquier sistema de tipado dinámico. El código de reflexión tiene la misma probabilidad de tener un error que el código que usa el tipo dinámico.

En lugar de pensar en términos de ventajas y desventajas, piense en términos más neutrales. La pregunta que haré es "¿Cuáles son las diferencias entre utilizar Reflection y usar el tipo dinámico?"

Primero: con Reflection obtienes exactamente lo que pediste. Con dynamic, obtienes lo que hubiera hecho el compilador de C# si se le hubiera proporcionado la información de tipo en el tiempo de compilación. Esos son potencialmente dos completamente cosas diferentes. Si tiene un MethodInfo para un método particular e invoca ese método con un argumento particular, entonces que es el método que se invoca, punto. Si usa "dinámico", entonces le está pidiendo al DLR que resuelva en tiempo de ejecución de qué se trata la opinión del compilador de C#, cuál es el método correcto para llamar. El compilador de C# podría elegir un método diferente al que realmente quería.

Segundo: con Reflection puede (si su código se concede niveles de confianza adecuadamente altos) hacer una reflexión privada. Puede invocar métodos privados, leer campos privados, etc. Si hacerlo es una buena idea, no lo sé. Sin duda me parece peligroso y estúpido, pero no sé cuál es tu aplicación. Con dynamic, obtienes el comportamiento que obtendrías del compilador C#; los métodos y campos privados no son visibles.

En tercer lugar: con Reflection, el código que escribe parece un mecanismo . Parece que está cargando un origen de metadatos, extrayendo algunos tipos, extrayendo algunas informaciones de métodos e invocando métodos en objetos del receptor a través de la información del método. Cada paso del camino parece el funcionamiento de un mecanismo . Con dinámica, cada paso del camino se ve como lógica de negocios. Invoca un método en un receptor de la misma forma que lo haría en cualquier otro código. ¿Lo que es importante? En algún código, el mecanismo es realmente lo más importante. En algunos códigos, la lógica comercial que el mecanismo implementa es lo más importante.Elija la técnica que enfatiza el nivel correcto de abstracción.

Cuarto: los costos de rendimiento son diferentes. Con Reflection no obtienes ningún comportamiento en caché, lo que significa que las operaciones son generalmente más lentas, pero no hay costo de memoria para mantener el caché y cada operación cuesta aproximadamente lo mismo. Con el DLR, la primera operación es muy lenta, ya que hace una gran cantidad de análisis, pero el análisis se almacena en caché y se reutiliza. Eso consume memoria, a cambio de una mayor velocidad en llamadas posteriores en algunos escenarios. Cuál es el balance correcto de velocidad y uso de memoria para su aplicación, no lo sé.

+0

Gracias por el análisis detallado de mi consulta. Fue bueno saber que DLR almacena en caché los resultados del análisis. – AbrahamJP

+0

+1 bonita respuesta detallada. – pqsk

+2

Esta es de lejos la mejor respuesta a esta pregunta –

11

Hay 4 grandes diferencias entre dinámica y reflexión. A continuación hay una explicación detallada de lo mismo. Referencia http://www.codeproject.com/Articles/593881/What-is-the-difference-between-Reflection-and-Dyna

Punto 1. Inspeccionar VS invocación

reflexión puede hacer dos cosas una es que puede inspeccionar meta-datos y el segundo también tiene la capacidad de invocar métodos en runtime.While en dinámico que sólo puede invocar métodos. Entonces, si estoy creando software como IDE visual studio, entonces la reflexión es el camino a seguir. Si solo quiero una invocación dinámica desde el código my C#, la dinámica es la mejor opción.

DynamicVsReflection

Punto 2. privada Vs invocación pública

Usted no puede invocar métodos privados usando dinámica. En la reflexión es posible invocar métodos privados.

Punto 3. El almacenamiento en caché

dinámico utiliza la reflexión interna y que también añade los beneficios de almacenamiento en caché. Por lo tanto, si desea invocar un objeto dinámicamente, Dynamic es lo mejor para obtener beneficios de rendimiento.

Punto 4. clases estáticas

dinámica es instancia específica: Usted no tiene acceso a miembros estáticos; tienes que usar Reflection en esos escenarios.