Estoy jugando con la API de reflexión C#. Puedo cargar fácilmente Type
información de clases, métodos, etc. en un ensamblado, sin embargo, ahora me pregunto cómo puedo cargar y leer el código dentro de un método?¿Puedo usar el reflejo para inspeccionar el código en un método?
Respuesta
respuesta básica:
Usted no puede con la API de reflexión (System.Reflection).
El motivo es que la API de reflexión está diseñada para trabajar con Metadatos (Tipo de clases, Nombre y Firma de métodos, ...) pero no en el nivel de datos (que sería la propia secuencia IL).
respuesta extendida:
Puede emitir (pero no leer) IL con System.Reflection.Emit (por ejemplo ILGenerator Class).
A través de MethodInfo.GetMethodBody()
puede obtener el flujo de IL binario para la implementación de un método. Pero eso suele ser completamente inútil por sí mismo.
Hay bibliotecas externas (como Cecil) que puede usar para leer/modificar/agregar/eliminar código dentro de un método.
¿No puede referirse al método a través de un delegado, luego crear un ExpressionTree del delegado e inspeccionar el árbol? –
@Matt Greer: No. No se puede "aplicar ingeniería inversa" al cuerpo del método de un delegado en un árbol de expresiones. – LBushkin
@Matt: Eso no te dará el código * dentro * del método, solo obtendrás 'MethodCallExpression' que te da acceso al mismo' MethodInfo' que podrías haber obtenido más directamente con la API de reflexión. – Aaronaught
No
Esta es una función programada para la próxima versión de C#. Puede usar CodeDom para obtener más información que reflexión, pero aún no puede interrogar al árbol de análisis.
Bueno, siempre hay mono, en mono el compilador es un servicio, y puede obtener los árboles de análisis en tiempo de ejecución.
La mejor pregunta es ¿por qué quieres?
Sí, debe haber una forma de lograr esto: la herramienta reflector .NET hace esto también. Sin embargo, no puedo decirte cómo se hace allí.
¿Por qué no refleja el reflector;) – ntziolis
Reflector no utiliza reflexión al menos no en el sentido de reflexión de .NET framework. En realidad, analiza el archivo PE y disimula el código IL de la sección .TEXT. Luego hace una coincidencia de patrones muy inteligente y genial para mapear/descompilar la IL de vuelta a un idioma de destino. –
Si no necesita hacer esto en tiempo real, eche un vistazo a Reflector. Puede desensamblar cualquier ensamblado .NET (incluidas las DLL principales de MS) y ver el código en el idioma de su elección. Esto puede ser muy educativo.
Actualización ¿Alguien ha intentado usar Reflector en reflector para descubrir cómo se hace esto?
Tenga en cuenta que esto no optimiza el código. Entonces, si se hizo una optimización del compilador a la IL, no se devuelve a su fuente de compilación original, sino a una versión optimizada escrita menos humanamente.Es una buena manera de ver lo que podrías estar haciendo más eficientemente. – DevelopingChris
No puede usar Reflector en Reflector. Pruébalo y verás, obtendrás una agradable sorpresa. – Aaronaught
Reflector está encriptado de modo que no se puede reflejar en sí mismo, creo que utilizaron DotFuscator para hacerlo. – DevelopingChris
Eso depende de lo que signifique leer el código. Hay 4 formas del código.
1- El código fuente, por ejemplo. el original C# o VB.NET - No, no pueden conseguir esto con la reflexión
2- El código IL simbólica - No, no puede conseguir esto con la reflexión
3- El código ensamblador JITed - No, no puede conseguir esto con la reflexión
4- Los bytes de IL, los bytes reales a los que se compila IL, este puede obtener.
Eche un vistazo a MethodBase.GetMethodBody() por ejemplo, puede obtener los bytes de IL, las variables locales, los marcos de excepción, etc. http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getmethodbody.aspx
'GetMethodBody()' es lo más cercano que puede obtener, creo. – LBushkin
tipo de can. La función relevante es MethodBase.GetMethodBody.
No es exactamente la API más útil. Puede obtener información básica sobre lo que hay dentro del método, y puede obtener IL como una matriz de bytes. Eso es todo.
Hay un poco mejor API en la biblioteca Mono.Cecil, que expone una clase MethodDefinition
con su propio MethodBody
aplicación real que contiene Instructions
, por lo que no tiene que interpretar el código de bytes en bruto. Aún así, si está buscando sacar el código C# a la Reflector, se sentirá profundamente decepcionado. Además, Cecil no está muy bien documentado.
Si aún quieres probar, entonces buena suerte.
Ahora hay bibliotecas/paquetes que le permiten inspeccionar el código del método e incluso descompilarlo a Expression
:
- 1. inspeccionar el código nativo
- 2. ¿Cómo puedo usar Rhino Mocks para inspeccionar qué valores se pasaron a un método?
- 3. Deserializar cadena JSON en C# sin usar el reflejo
- 4. ¿Puedo usar el método viewDidLoad en UITableviewCell?
- 5. ¿Cómo puedo usar el reflejo para devolver todas las clases subclases desde un genérico, sin dar un tipo genérico específico?
- 6. Silverlight: ¿No se puede usar el reflejo en GetValue de un campo en XAP?
- 7. ¿Puedo convertir el siguiente código para usar genéricos?
- 8. Inspeccionar el valor de retorno de un método en el jdb
- 9. ¿Cómo puedo inspeccionar el objeto ventana para safari móvil?
- 10. ¿Cómo puedo usar IE8 Developer Tools para inspeccionar el tráfico de la red?
- 11. Python reflexión - ¿Puedo usar esto para obtener el código fuente de una definición del método
- 12. ¿Cómo puedo generar un evento mediante reflejo en .NET/C#?
- 13. Deshabilitar reflejo de Java para el hilo actual
- 14. ¿Cómo puedo usar Bochs para ejecutar el código de ensamblado?
- 15. ¿Debo dejar el reflejo de bluetooth pirateado en el código de producción?
- 16. ¿Cómo puedo usar el código C++ para interactuar con PHP?
- 17. ¿Puedo usar DoxyGen para documentar el código de ActionScript?
- 18. excepción de acceso al invocar el método de una clase anónima mediante el reflejo de java
- 19. Llamar a un método genérico por reflejo en java
- 20. cómo inspeccionar/iterar sobre un objeto en el nodo?
- 21. ¿Puedo usar un método que anule un método no virtual?
- 22. En .NET, ¿puedes usar el reflejo para obtener todos los métodos no heredados de una clase?
- 23. ¿Puedo usar el patrón de decorador para envolver un cuerpo de método?
- 24. Código de Python para analizar e inspeccionar C++
- 25. Cómo usar el método addCustomRequestHeader en selenio?
- 26. git inspeccionar el tiempo en el que se pulsó commit
- 27. cómo usar el método onClickListener de Button en un ListView
- 28. ¿Usar la afeitadora para generar el código?
- 29. ¡Nunca use reflejo en el código de producción! ¿Qué hay de Python?
- 30. ¿Cómo puedo pasar un método adquirido por reflexión en C# a un método que acepta el método como delegado?
Lo es el escenario que hace que esto sea útil? Rompe uno de los inquilinos fundamentales de OO que es encapsulación. Pero, además, el código como IL no es realmente lo mismo. – DevelopingChris
@DevelopingChris: si está escribiendo una herramienta de depuración o análisis de código, puede ser útil poder cargar un ensamblaje y analizar el cuerpo de un método. Esto es, de hecho, lo que hacen las herramientas como FxCop. – LBushkin
El público objetivo de .NET son las corporaciones estadounidenses (y, secundariamente, algunas pequeñas empresas). Si pudiera eludir la ofuscación de .NET, el software (caro de producir) podría volar fácilmente en las yemas de los dedos de la competencia. – micahhoover