2012-06-14 32 views
6

Estoy seguro de que esta pregunta ha sido respondida en alguna parte, pero estoy teniendo grandes problemas para encontrar la combinación correcta de palabras clave para encontrarla.Método de ejecución en dinámico

Tengo curiosidad por saber si su posible hacer algo como esto:

dynamic someObj = new SomeObject(); 

var methodName = "someMethodName"; 

// execute methodName on someObj 

básicamente me gustaría saber si es posible ejecutar un método en un objeto dinámico utilizando una variable que almacena el nombre de métodos.

+0

'object' es el nombre del alias C# para la clase' System.Object'; debería cambiarle el nombre a, digamos, 'obj'. – dasblinkenlight

+0

¿Por qué harías eso? Tendría que usar la reflexión de vainilla para encontrar el método que tenía ese nombre. No tiene sentido usar dinámica si vas a hacer eso. –

+4

No, la dinámica es un requisito aquí. Estoy usando SignalR y exponen un objeto dinámico que representa tus conexiones de clientes actuales. En ese objeto puede llamar a métodos arbitrarios que se correlacionan con puntos finales de JavaScript frontales. Estoy tratando de encapsular esta lógica en una clase base, por lo que no interactúo explícitamente con la arquitectura de Hub para agregar un nivel de abstracción entre mi código y el código de terceros – devshorts

Respuesta

7

Puede hacerlo en cualquier objeto, no necesariamente dynamic usando reflection.

object obj = new SomeObject(); 
var meth = obj.GetType().GetMethod("someMethodName"); 
meth.Invoke(obj, new object[0]); // assuming a no-arg method 

Cuando se utiliza dynamic, puede utilizar cualquier identificador para un nombre de método, y el compilador no se quejará:

dynamic obj = MakeSomeObject(); 
obj.someMethodName(); // Compiler takes it fine, even if MakeSomeObject returns an object that does not declare someMethodName() 
+1

+1, lo que es sorprendente que GetType() funcione en un objeto dinámico, pero no lo mencionó de esa manera en su solución – Milimetric

+1

@Milimetric: no existe el "objeto dinámico". Las variables 'dynamic' contienen objetos regulares. Esto no funcionará con 'IDynamicMetaObject'. – SLaks

+0

Quise decir un objeto escrito con 'dynamic' en lugar de un objeto escrito con' var' o 'DansAwesomeClass' – Milimetric

2

Bueno, en realidad no necesita "someMethodName" entre comillas. Que acaba de hacer esto (lista completa de programas):

class Program 
{ 
    static void Main(string[] args) 
    { 
     dynamic obj = new SomeObject(); 
     obj.someMethodName("hello"); 
    } 
} 

public class SomeObject 
{ 
    public void someMethodName(string message) 
    { 
     Console.WriteLine(message); 
    } 
} 

En caso de que su nombre de método proviene de algún lugar del mal como JavaScript o algo así, entonces usted puede hacer esto:

class Program 
{ 
    static void Main(string[] args) 
    { 
     dynamic obj = new SomeObject(); 
     var meth = obj.GetType().GetMethod("someMethodName"); 
     meth.Invoke(obj, new object[1]{"hello"}); 
    } 
} 

public class SomeObject 
{ 
    public void someMethodName(string message) 
    { 
     Console.WriteLine(message); 
    } 
} 
+0

Gracias, la pregunta viene de JavaScript. Estoy tratando de encapsular la mecánica SignalR, que es la forma en que se presentó este problema – devshorts

+1

genial :) bueno, lo sorprendente es que puedes llamar a GetType() en un objeto dinámico. Pero en este caso, creo que la respuesta que usted aceptó es mejor porque solo está usando un sencillo y genérico System.Object en lugar de dinámico que podría no ser tan liviano. Ah, y la dinámica es más difícil de depurar: he logrado bloquear Visual Studio algunas veces al agregar dinámica al reloj. – Milimetric

1

Sobre la base de sus comentarios, el requisito es poder llamar funciones de un proxy de cliente dinámico SignalR utilizando una cadena. Intentar utilizar el reflejo para hacer esto, es decir: .GetType().GetMethod(functionName) no funciona, como no lo haría con ningún objeto dinámico.

Sin embargo, se puede hacer utilizando el método Invoke del objeto dinámico.

var functionName = "alertAllUsers"; 
var message = "Hello!"; 
var groupID = "1"; 

var connection = GlobalHost.ConnectionManager.GetHubContext<SomeHub>(); 
connection.Clients.Group(groupID).Invoke(functionName, message); 
Cuestiones relacionadas