2009-12-08 13 views
16

¿Cómo puedo obtener los valores de parms (en un bucle mediante reflexión)? En la pregunta anterior, alguien me mostró cómo recorrer los parms usando reflexión.C# Obteniendo el valor de los parms usando la reflexión

static void Main(string[] args) 
{ 
    ManyParms("a","b","c",10,20,true,"end"); 
    Console.ReadLine(); 
} 

static void ManyParms(string a, string b, string c, int d, short e, bool f, string g) 
{ 
    var parameters = MethodBase.GetCurrentMethod().GetParameters(); 
    foreach (ParameterInfo parameter in parameters) 
    { 
     string parmName = parameter.Name; 
     Console.WriteLine(parmName); 
     //Following idea required an object first 
     //Type t = this.GetType(); 
     //t.GetField(parmName).GetValue(theObject)); 

    } 
} 

Si tiene que saber por qué quiero hacer esto, por favor ver aquí: .NET Reflection of all method parameters


Gracias todos - parece que en Python, Perl, PHP esto sería fácil.
Aunque puede que no sea reflejo, si uso el reflejo para obtener el nombre del campo, parece que habría una manera fácil y dinámica de obtener el valor basado en el nombre. No he probado AOP (Programación Orientada a Aspectos) aún las soluciones. Esta es una de esas cosas que si no puedo hacerlo en una o dos horas, probablemente no lo haga.

+0

Tal vez algo se podría hacer mediante la inspección de la reflexión a través de la máquina de estado que se genera cuando se utiliza un IEnumerable? Solo una idea de la que no sabría cómo darme cuenta :-) (Comenta aquí debido a una pregunta duplicada hoy) – Jbjstam

Respuesta

19

No se puede, básicamente, - al menos no sin enganchar en el debugger/profiling API.

En teoría no podría haber alguna manera de los valores de los parámetros StackFrame clase exponiendo, pero no es así - y sospecho que con el fin de hacerlo, habría que eliminar varias optimizaciones.

4

No se puede a través de la reflexión, y no se debe hacer de todos modos.

Si necesita este tipo de funcionalidad, utilizar un proxy, por ejemplo, a través de una implementación RealProxy que intercepta la llamada por usted. Luego, puede verificar y modificar cualquier parámetro antes de que se realice la llamada real (o incluso no realizar la llamada original, eso depende de usted).

+0

Voy a analizar esto si tengo más tiempo. Sin embargo, si ve mi publicación referenciada arriba, estoy usando Microsoft Host Integration Server y específicamente HIP, y no estoy seguro de cómo jugará el proxy con esos tipos. – NealWalters

4

No puede hacer eso. La reflexión funciona sobre los metadatos incrustados durante la compilación y en ese momento los valores de los parámetros no se conocen.

+4

Pero puede usar la reflexión para obtener valores de propiedades en objetos, que no se conocen en tiempo de compilación. – NealWalters

4

Ha considerado el uso de AOP, como PostSharp?

Puede obtener acceso a los valores de los argumentos antes de que se ejecute su método, y su código se reduciría así a una clase de atributo reutilizable y un atributo aplicado a los métodos que necesitan esta verificación.

2

No se puede obtener el valor de los parámetros del método mediante reflexión. Porque la reflexión devuelve la información de metadatos. Si desea obtener el valor de un campo o propiedad específico, debe usar también una instancia (como ya sabe).

Hay varias maneras de obtener el valor de un parámetro utilizando la tubería interna del marco .NET - API es decir, perfilador y API depurador.

Puede usar AOP para lo que está tratando de hacer, existe un proyecto Codeplex llamado CThru que podría ayudarlo: mediante CThru puede interceptar el método cuando se lo llama y obtener los parámetros con los que fue llamado.

32

Puede abrirse paso en torno a este mediante la creación de un tipo anónimo dentro de su método y el aprovechamiento de inicializadores de proyección. A continuación, puede interrogar las propiedades del tipo anónimo mediante la reflexión. Por ejemplo:

static void ManyParms(
    string a, string b, string c, int d, short e, bool f, string g) 
{ 
    var hack = new { a, b, c, d, e, f, g }; 

    foreach (PropertyInfo pi in hack.GetType().GetProperties()) 
    { 
     Console.WriteLine("{0}: {1}", pi.Name, pi.GetValue(hack, null)); 
    } 
} 
+5

Eso requiere que cambies el contenido de tu método. Si vas a hacer eso, puedes informar los valores de todos modos. Esta sintaxis hace que sea un poco más fácil hacerlo, pero dudo que realmente ayude al OP. –

+0

@Jon: tienes razón, por supuesto, pero esto es * mucho * menos tipeo que hacerlo manualmente, y porque no hay varias líneas codificadas como 'Console.WriteLine (" a: "+ a)' etc. , hay mucho menos margen para el error. – LukeH

+2

Es un workarround brillante – Serge

Cuestiones relacionadas