valores retorna metodos metodo generar funciones español ejemplos como c# reflection dynamic

retorna - metodos y funciones en c#



¿Cómo puedo obtener los valores de los parámetros de un método de llamada? (5)

Jonathan Keljo en Microsoft dice, en esta publicación del grupo de noticias ,:

Desafortunadamente, la única manera fácil de obtener información de argumento de una pila de llamadas hoy es con un depurador. Si intenta hacer esto como parte del registro de errores en una aplicación y planea enviar el registro de errores nuevamente a su departamento de soporte, esperamos que use minivolcados para ese propósito en el futuro. (Hoy, usar un minivolcado con código administrado es un poco problemático ya que no incluye suficiente información para obtener un seguimiento de la pila de manera predeterminada. Un minivolcado con heap es mejor, pero no tan "mini" si sabes a qué me refiero).

Un purista diría que permitir que las personas escriban código que pueda obtener argumentos de las funciones en otra parte de la pila de llamadas los alentaría a romper la encapsulación y crear un código que es muy frágil frente al cambio. (Su escenario no tiene este problema en particular, pero he escuchado otras solicitudes para esta función). De todos modos, la mayoría de esas solicitudes se pueden resolver de otras maneras, como el uso de tiendas de hilos). Sin embargo, lo que es más importante, habría implicaciones de seguridad de esto: las aplicaciones que permiten complementos estarían en riesgo de que esos complementos rasparan la pila de información confidencial. Definitivamente podríamos señalar que la función requiere plena confianza, pero eso la haría inservible para casi todos los escenarios de los que he oído hablar.

Jonathan

Entonces ... Supongo que la respuesta corta es "No puedo". Eso apesta.

Pregunta

Estoy escribiendo un código que necesita para obtener los valores de los parámetros del método que llamó a la clase. Sé cómo llegar hasta la matriz ParameterInfo [], pero no sé cómo obtener los valores. ¿Esto es posible?

Si es así, creo que tiene algo que ver con el uso de la propiedad MethodBody del objeto MethodInfo, que te permite inspeccionar la secuencia IL, incluidas las propiedades, pero no sé cómo hacerlo, y no he encontrado código aplicable en Google.

Código

// Finds calling method from class that called into this one public class SomeClass { public static void FindMethod() { for (int i = 1; i < frameCount; i++) { var frame = new StackFrame(i); var methodInfo = frame.GetMethod(); if (methodInfo.DeclaringType != this.GetType()) { string methodName = frame.GetMethod().Name; var paramInfos = methodInfo.GetParameters(); // Now what?? How do I get the values from the paramInfos break; } else if (i == frameCount - 1) { throw new TransportException("Couldn''t find method name"); } } } }



No puede hacerlo sin introspectar la pila usted mismo (y esto es frágil ya que muchas optimizaciones pueden significar que el marco de la pila no es lo que espera, o incluso que el parámetro pasado no es de hecho lo que la firma del método sugeriría (es perfectamente posible para un compilador de JIT optimizado para detectar que solo está utilizando un subcampo de un objeto / estructura y pasarlo en su lugar).

ParameterInfo simplemente le indica la firma del método como compilado, no los valores que se pasaron.

La única manera realista de lograr esto automáticamente es a través de la inyección de código (a través de algo como AOP) para crear los datos y hacer lo que quiera con ellos en base al análisis de IL.

Esto generalmente no es una buena idea, si necesita depurar algo, use un depurador, si necesita registrar algo, explíquelo.

Para ser claros, las técnicas reflexivas simples no pueden lograr lo que deseas con total generalidad


No puedes hacerlo con StackFrame o StackTrace. Sin embargo, puede emplear algún marco de interceptación (como material AOP de Spring.NET) para que pueda obtener los valores de los parámetros.


Sí, usted puede hacer esto.

Lo que necesita hacer es usar un desensamblador de IL (que se puede lograr dentro del espacio de nombres System.Reflection.Emit) para encontrar el operando que contiene el valor del parámetro que está buscando.

Comience con esta pregunta ASÍ: Reflexión C # y encontrar todas las referencias

Luego use la clase mencionada en las respuestas (de Mono.Reflection) para hacer su inspección. Algo como esto:

var instructions = method.GetInstructions(); foreach (var instruction in instructions) { var methodInfo = instruction.Operand as MethodInfo; if(methodInfo == null) { continue; } if (instruction.OpCode.Name.Equals("call") && methodInfo.Name.Equals("YourMethodHere")) { var value = (CastToMyType)instruction.Previous.Operand; // Now you have the value... } }