c# - software - reflection programming
Dynamic Lang. Runtime vs Reflection (6)
Código legible / Maintainable
Ciertamente cierto en mi experiencia.
Menos líneas de código.
No significativamente, pero ayudará.
Afecta el rendimiento de la aplicación.
Muy ligeramente. 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 el comentario a continuación]
Parece que Dynamic Language Runtime utiliza Reflection y las mejoras de rendimiento solo se deben a técnicas de caché.
La tipificación dinámica podría convertirse en un caldo de cultivo para errores difíciles de encontrar.
Esto puede ser cierto; 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 verdad. 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.
Un profesional importante que te falta es la interoperabilidad mejorada con los componentes COM / ATL.
Estoy planeando usar 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.
Después de donde los pros, pude encontrar con respecto a la palabra clave dinámica:
- Código legible / Maintainable.
- Menos líneas de código.
Mientras que los aspectos negativos asociados con el uso de la palabra clave dinámica, vine a escuchar fue como:
- Afecta el 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 un caldo de cultivo para errores difíciles de encontrar.
- Afecta la interoperabilidad con versiones anteriores de .NET.
Por favor, ayúdame a saber si los pros y los contras que encontré son razonables o no.
Por favor, ayúdame a saber si los pros y los contras que encontré son razonables o no.
La preocupación que tengo con sus pros y 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 usar Reflection y usar el tipo dinámico?"
Primero: con Reflection obtienes exactamente lo que pediste. Con dynamic, obtienes lo que el compilador de C # habría hecho si se le hubiera proporcionado la información de tipo en tiempo de compilación . Esas son potencialmente dos cosas completamente diferentes. Si tiene un MethodInfo para un método particular e invoca ese método con un argumento particular, entonces ese 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 puedes (si tu código tiene 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.
Tercero: 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 se ve como el funcionamiento de un mecanismo . Con la dinámica, cada paso del camino se parece a la 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é.
En la mayoría de los casos, usar 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) )
Use la palabra clave con moderación, donde tenga sentido, y asegúrese de que dicho código tenga amplias pruebas de unidad. No lo use donde no sea necesario o cuando la inferencia de tipo (por ejemplo var
) pueda hacer lo mismo.
Editar: Menciona a continuación que está haciendo esto para complementos. El Marco de Extensibilidad Administrada fue diseñado con esto en mente; puede ser una mejor opción que la palabra clave dynamic
y la reflexión.
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. Inspeccione VS Invoke
La reflexión puede hacer dos cosas: una es que puede inspeccionar los metadatos y la segunda también tiene la capacidad de invocar métodos en el tiempo de ejecución. Mientras que en Dynamic solo podemos 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.
Punto 2. Privado Vs Public Invoke
No puede invocar métodos privados utilizando dynamic. En la reflexión es posible invocar métodos privados.
Punto 3. Almacenamiento en caché
Dynamic usa la reflexión internamente y también agrega 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
La dinámica es específica de la instancia: no tiene acceso a miembros estáticos; tienes que usar Reflection en esos escenarios.
La forma en que veo todos tus inconvenientes para usar dinámica, excepto la interoperabilidad con versiones anteriores de .NET, también está presente cuando utilizas Reflection:
Afecta el rendimiento de la aplicación
Si bien afecta el rendimiento, también lo hace el uso de 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
La palabra clave dinámica es internamente un contenedor de Reflexión
Incluso si fuera cierto (ver arriba), ¿cómo sería eso un punto negativo? Si se ajusta o no Reflexión no debe influir en su aplicación en ningún asunto importante.
La tipificación dinámica podría convertirse en caldo de cultivo para errores difíciles de encontrar
Si bien esto es cierto, siempre y cuando lo uses con moderación, no debería ser un gran 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 eso tienes que decidir cuánto te preocupa.
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.