2012-06-14 5 views
6

Sono sicuro che questa domanda è stato risposto da qualche parte, ma sto avendo grossi problemi a trovare la giusta combinazione di parole chiave per trovarlo.metodo Execute sulla dinamica

io sono curioso di sapere se la sua possibilità di fare qualcosa di simile:

dynamic someObj = new SomeObject(); 

var methodName = "someMethodName"; 

// execute methodName on someObj 

Io fondamentalmente voglio sapere se la sua possibile eseguire un metodo su un oggetto dinamico utilizzando una variabile che memorizza il nome metodi.

+0

'object' è il nome del C# alias per la classe' System.Object'; dovresti rinominarlo, per esempio, 'obj'. – dasblinkenlight

+0

Perché dovresti farlo? Dovresti usare la riflessione alla vaniglia per trovare il metodo che aveva quel nome. Non ha senso usare la dinamica se hai intenzione di farlo. –

+4

No, la dinamica è un requisito qui. Sto usando SignalR e espongono un oggetto dinamico che rappresenta le tue attuali connessioni client. Su quell'oggetto puoi chiamare metodi arbitrari che si associano agli endpoint JavaScript frontati. Sto cercando di incapsulare questa logica in una classe base in modo non esplicitamente interagire con l'architettura Hub per aggiungere un livello di astrazione tra il mio codice e il codice di 3a parte – devshorts

risposta

7

È possibile farlo su qualsiasi oggetto, non necessariamente uno dynamic uno utilizzando reflection.

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

Quando si utilizza dynamic, è possibile utilizzare qualsiasi identificatore per un nome di metodo, e il compilatore non si lamentano:

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

+1, sorprendente che GetType() funziona su un oggetto dinamico, ma non hai lista in questo modo nella soluzione – Milimetric

+1

@Milimetric: Non esiste una cosa come un "oggetto dinamico". Le variabili 'dynamic' contengono oggetti regolari. Questo non funzionerà con 'IDynamicMetaObject'. – SLaks

+0

Intendevo un oggetto digitato con 'dynamic' in opposizione a un oggetto digitato con' var' o 'DansAwesomeClass' – Milimetric

2

Bene, in realtà non è necessario "someMethodName" tra virgolette. Basta fare questo (elenco completo del programma):

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); 
    } 
} 

Nel caso il vostro nome del metodo viene da un posto male, come JavaScript o qualcosa, allora si può fare questo:

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

Grazie, la domanda viene da JavaScript. Sto cercando di incapsulare meccanici SignalR che è come questo problema si è presentato – devshorts

+1

cool :) beh la cosa sorprendente è che puoi chiamare GetType() su un oggetto dinamico. Ma in questo caso, penso che la risposta che hai accettato sia migliore perché stai semplicemente usando un semplice vecchio System.Object generico anziché dinamico che potrebbe non essere così leggero. Oh, e la dinamica è più difficile da eseguire il debug: sono riuscito a bloccare Visual Studio alcune volte aggiungendo dinamiche al Watch – Milimetric

1

sulla base di osservazioni, il requisito è essere in grado di chiamare le funzioni di un proxy client dinamico SignalR utilizzando una stringa. Cercando di utilizzare la riflessione per fare ciò, ad esempio: .GetType().GetMethod(functionName) non funziona, come non farebbe per qualsiasi oggetto dinamico.

Si può comunque essere fatta utilizzando il metodo dell'oggetto dinamico Invoke.

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

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