2012-06-14 15 views
6

Ich bin sicher, dass diese Frage irgendwo beantwortet wurde, aber ich habe große Probleme, die richtige Kombination von Keywords zu finden, um es zu finden.Execute Methode auf dynamische

Ich bin neugierig, ob seine mögliche, so etwas zu tun:

dynamic someObj = new SomeObject(); 

var methodName = "someMethodName"; 

// execute methodName on someObj 

Ich möchte im Grunde wissen, ob ihre möglich, ein Verfahren auf einem dynamischen Objekt mit einer Variablen auszuführen, die die Methoden Namen speichert.

+0

'Objekt' ist der Name des C# -Alias ​​für die 'System.Object'-Klasse; Sie sollten es umbenennen, zum Beispiel, "obj". – dasblinkenlight

+0

Warum würden Sie das tun? Sie müssen die Vanilla-Reflektion verwenden, um die Methode mit diesem Namen zu finden. Kein Grund, dynamisch zu arbeiten, wenn Sie das tun. –

+4

Nein, dynamisch ist hier eine Voraussetzung. Ich benutze SignalR und sie legen ein dynamisches Objekt offen, das deine aktuellen Client-Verbindungen darstellt. Auf diesem Objekt können Sie beliebige Methoden aufrufen, die Frontend-JavaScript-Endpunkten zugeordnet sind. Ich versuche, diese Logik in einer Basisklasse zu kapseln, also interagiere ich nicht explizit mit der Hub-Architektur, um eine Abstraktionsebene zwischen meinem Code und dem 3rd-Party-Code – devshorts

Antwort

7

Sie können es auf jeder Objekt, nicht unbedingt ein dynamic eins mit reflection tun.

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

Wenn Sie dynamic verwenden, können Sie jede Kennung für einen Methodennamen verwenden, und der Compiler nicht beklagen:

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

+1, überraschend, dass GetType() auf einem dynamischen Objekt funktioniert, aber Sie haben es in Ihrer Lösung nicht so aufgelistet – Milimetric

+1

@Milimetric: Es gibt kein "dynamisches Objekt". 'dynamische' Variablen enthalten reguläre Objekte. Dies funktioniert nicht mit 'IDynamicMetaObject'. – SLaks

+0

Ich meinte ein Objekt, das mit 'dynamic' typisiert wurde, im Gegensatz zu einem Objekt, das mit' var' oder 'DansAwesomeClass' typisiert wurde. – Milimetric

2

Nun, Sie brauchen tatsächlich "someMethodName" in Anführungszeichen. Sie tun gerade diese (volle Programmliste):

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

Wenn Ihr Methodennamen von einem bösen Ort wie Javascript oder etwas kommt, dann können Sie dies tun:

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

Danke, die Frage kommt von JavaScript. Ich versuche SignalR-Mechanik zu kapseln, wie sich dieses Problem präsentierte – devshorts

+1

cool :) Nun, die überraschende Sache ist, dass Sie GetType() auf einem dynamischen Objekt aufrufen können. Aber in diesem Fall denke ich, dass die Antwort, die Sie akzeptiert haben, besser ist, weil Sie nur ein einfaches altes generisches System.Object verwenden, im Gegensatz zu dynamischen, die möglicherweise nicht so leicht sind. Oh, und Dynamik ist schwieriger zu debuggen - ich habe es geschafft, Visual Studio ein paar Mal zum Absturz zu bringen, während ich der Uhr Dynamik hinzufügte – Milimetric

1

Basierend auf Ihre Kommentare, Voraussetzung ist, dass Funktionen eines SignalR Dynamic Client Proxy über eine Zeichenkette aufgerufen werden können. Der Versuch, eine Reflektion zu verwenden, um dies zu tun, zB: .GetType().GetMethod(functionName) funktioniert nicht, wie es bei keinem dynamischen Objekt der Fall wäre.

Es kann jedoch mit der Invoke Methode des dynamischen Objekts durchgeführt werden.

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

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