2009-06-02 9 views
25

Tengo una lista desplegable que se completa inspeccionando los métodos de una clase e incluyendo aquellos que coinciden con una firma específica. El problema es tomar el elemento seleccionado de la lista y hacer que el delegado llame a ese método en la clase. El primer método funciona, pero no puedo descifrar parte del segundo.Obtención de un delegado de methodinfo

Por ejemplo,

public delegate void MyDelegate(MyState state); 

public static MyDelegate GetMyDelegateFromString(string methodName) 
{ 
    switch (methodName) 
    { 
     case "CallMethodOne": 
      return MyFunctionsClass.CallMethodOne; 
     case "CallMethodTwo": 
      return MyFunctionsClass.CallMethodTwo; 
     default: 
      return MyFunctionsClass.CallMethodOne; 
    } 
} 

public static MyDelegate GetMyDelegateFromStringReflection(string methodName) 
{ 
    MyDelegate function = MyFunctionsClass.CallMethodOne; 

    Type inf = typeof(MyFunctionsClass); 
    foreach (var method in inf.GetMethods()) 
    { 
     if (method.Name == methodName) 
     { 
      //function = method; 
      //how do I get the function to call? 
     } 
    } 

    return function; 
} 

¿Cómo llego por las secciones del segundo método funcione? ¿Cómo echo el MethodInfo en el delegado?

Gracias!

Editar: Aquí está la solución de trabajo.

public static MyDelegate GetMyDelegateFromStringReflection(string methodName) 
{ 
    MyDelegate function = MyFunctionsClass.CallMethodOne; 

    Type inf = typeof(MyFunctionsClass); 
    foreach (var method in inf.GetMethods()) 
    { 
     if (method.Name == methodName) 
     { 
      function = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), method); 
     } 
    } 

    return function; 
} 

Respuesta

21

Tendrá que llamar a algún tipo de Delegate.CreateDelegate(), dependiendo de si el método en cuestión es un método estático o instancia.

+1

Gracias nkohari, funcionó exactamente como yo lo necesitaba. –

8
private static Delegate CreateDelegate(this MethodInfo methodInfo, object target) { 
    Func<Type[], Type> getType; 
    var isAction = methodInfo.ReturnType.Equals((typeof(void))); 
    var types = methodInfo.GetParameters().Select(p => p.ParameterType); 

    if (isAction) { 
     getType = Expression.GetActionType; 
    } 
    else { 
     getType = Expression.GetFuncType; 
     types = types.Concat(new[] { methodInfo.ReturnType }); 
    } 

    if (methodInfo.IsStatic) { 
     return Delegate.CreateDelegate(getType(types.ToArray()), methodInfo); 
    } 

    return Delegate.CreateDelegate(getType(types.ToArray()), target, methodInfo.Name); 
} 
+0

Esta debería ser la respuesta aceptada: soluciona la pregunta directamente – Graviton

+1

@Graviton Depende de si tiene la firma del método como un tipo de 'Delegado' o no. En este caso, el OP parece indicar que puede presuponer 'MyDelegate', en cuyo caso Nate y la solución que OP incorporó son las mejores. Esta, por otro lado, es una respuesta excelente para la * otra * pregunta, que es qué hacer si no tiene acceso al tipo apropiado de 'Delegado' (es decir, típicamente, obtuvo un 'Método de información 'fuera de el azul solo por su nombre) ... pero necesita precisamente ese tipo de delegado para crear un delegado (un problema de huevo y gallina '.NET' bastante notorio). –

Cuestiones relacionadas