2011-10-19 14 views
9

Tengo una clase con un método privado estático con un parámetro opcional. ¿Cómo lo invoco desde otra clase a través de Reflection? Hay un question similar, pero no aborda el método estático ni los parámetros opcionales.¿Cómo ejecutar un método estático privado con parámetros opcionales a través de la reflexión?

public class Foo { 
    private static void Bar(string key = "") { 
     // do stuff 
    } 
} 

¿Cómo se invocan Foo.Bar("test") y Foo.Bar() (por ejemplo, sin pasar el parámetro opcional)?

Respuesta

20

Los valores de parámetros opcionales en C# se compilan mediante inyección de esos valores en el callsite. Es decir. a pesar de que su código es

Foo.Bar() 

El compilador genera realmente una llamada como

Foo.Bar("") 

Al encontrar el método que necesita para tratar los parámetros opcionales como parámetros regulares.

var method = typeof(Foo).GetMethod("Bar", BindingFlags.Static | BindingFlags.NonPublic); 

Si usted sabe exactamente qué valores desea invocar el método con el que puede hacer:

method.Invoke(obj: null, parameters: new object[] { "Test" }); 

Si sólo tiene algunos de los parámetros y desea honrar los valores de la falta de pago se tiene que inspeccionar los objetos ParameterInfo del método para ver si los parámetros son opcionales y cuáles son esos valores. Por ejemplo, para imprimir los valores por defecto de los parámetros que se podría utilizar el siguiente código:

foreach (ParameterInfo pi in method.GetParameters()) 
{ 
    if (pi.IsOptional) 
    { 
     Console.WriteLine(pi.Name + ": " + pi.DefaultValue); 
    } 
} 
+0

¿Qué pasa con la parte método estático? – AngryHacker

+0

@AngryHacker use 'BindingFlags.Static' (ver respuesta actualizada) – marcind

2

El uso de esta clase

public class Foo 
    { 
    private static void Bar(string key = "undefined key", string value = "undefined value") 
    { 
     Console.WriteLine(string.Format("The key is '{0}'", key)); 
     Console.WriteLine(string.Format("The value is '{0}'", value)); 
    } 
    } 

Puede utilizar el siguiente código para llamar con los valores por defecto

MethodInfo mi = typeof(Foo).GetMethod("Bar", BindingFlags.NonPublic | BindingFlags.Static); 
    ParameterInfo[] pis = mi.GetParameters(); 

    object[] parameters = new object[pis.Length]; 

    for (int i = 0; i < pis.Length; i++) 
    { 
    if (pis[i].IsOptional) 
    { 
     parameters[i] = pis[i].DefaultValue; 
    } 
    } 

    mi.Invoke(null, parameters); 

Si el método tenía algunos parámetros no opcionales, tendrá que insertarlos en la matriz de parámetros antes de invocar el método.

por ejemplo

private static void Bar(int number, string key = "undefined key", string value = "undefined") 

Requeriría que hagas

parameters[0] = "23" 

Antes de invocar

Cuestiones relacionadas