7

I am sure this question has been answered somewhere but I'm having major problems finding the right combination of keywords to find it.

I am curious to know if its possible to do something like this:

dynamic someObj = new SomeObject();

var methodName = "someMethodName";

// execute methodName on someObj

I basically want to know if its possible to execute a method on a dynamic object using a variable that stores the methods name.

devshorts
  • 8,572
  • 4
  • 50
  • 73
  • `object` is the name of the C# alias for the `System.Object` class; you should rename it to, say, `obj`. – Sergey Kalinichenko Jun 14 '12 at 22:52
  • Why would you do that? You'd have to use vanilla reflection to find the method that had that name. No point in using dynamic if you are going to do that. – Tony Hopkinson Jun 14 '12 at 22:54
  • 4
    No, dynamic is a requirement here. I'm using SignalR and they expose a dynamic object representing your current client connections. On that object you can call arbitrary methods that map to fronted JavaScript endpoints. I am trying to encapsulate this logic in a base class so I don't explicitly interact with the Hub architecture to add a level of abstraction between my code and the 3rd party code – devshorts Jun 15 '12 at 11:31
  • dasblinekn, it was just pseudo code – devshorts Jun 15 '12 at 11:32
  • 2
    @devshorts. I asked why, and avoiding run time binding failures from 3rd party code is a good reason. – Tony Hopkinson Jun 18 '12 at 22:23

4 Answers4

7

You can do it on any object, not necessarily a dynamic one using reflection.

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

When you use dynamic, you can use any identifier for a method name, and the compiler will not complain:

dynamic obj = MakeSomeObject();
obj.someMethodName(); // Compiler takes it fine, even if MakeSomeObject returns an object that does not declare someMethodName()
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    +1, surprising that GetType() works on a dynamic object, but you didn't list it that way in your solution – Milimetric Jun 14 '12 at 23:05
  • 1
    @Milimetric: There is no such thing as a "dynamic object". `dynamic` variables hold regular objects. This will not work with `IDynamicMetaObject`. – SLaks Jun 15 '12 at 12:36
  • I meant an object typed with `dynamic` as opposed to an object typed with `var` or `DansAwesomeClass` – Milimetric Jun 15 '12 at 14:03
  • Thanks a lot for the method. But how can I catch returned values? – Erçin Dedeoğlu Jul 19 '14 at 08:53
  • @ErçinDedeoğlu Assign the results of the call to a variable of type `object` or `dynamic`, that's going to capture the return value. – Sergey Kalinichenko Jul 19 '14 at 09:50
  • The the context of a SignalR dynamic client proxy, `.GetType().GetMethod("someMethodName")` will return null. – Stumblor Sep 15 '15 at 08:33
  • @Stumblor If OP wanted an answer in the context of SignalR, he would have mentioned SignalR *in the body of his question*, or at the very least tagged the question for SignalR. – Sergey Kalinichenko Sep 15 '15 at 09:08
2

Well, you actually don't need "someMethodName" in quotes. You just do this (full program listing):

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

In case your method name comes from some evil place like javascript or something, then you can do this:

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);
    }
}
Milimetric
  • 13,411
  • 4
  • 44
  • 56
  • Thanks, the question does come from JavaScript. I'm trying to encapsulate SignalR mechanics which is how this issue presented itself – devshorts Jun 15 '12 at 11:27
  • 1
    cool :) well the surprising thing is that you can call GetType() on a dynamic object. But In this case, I think the answer you accepted is better because you're just using a plain old generic System.Object as opposed to dynamic which might not be as lightweight. Oh, and dynamic is harder to debug - I've managed to crash Visual Studio a few times while adding dynamics to the Watch – Milimetric Jun 15 '12 at 12:08
2

Based on your comments, the requirement is to be able to call functions of a SignalR dynamic client proxy using a string. Trying to use reflection to do this, ie: .GetType().GetMethod(functionName) doesn't work, as it wouldn't for any dynamic object.

It can however be done using the Invoke method of the dynamic object.

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

var connection = GlobalHost.ConnectionManager.GetHubContext<SomeHub>();
connection.Clients.Group(groupID).Invoke(functionName, message);
Stumblor
  • 1,118
  • 8
  • 16
0

You can do it using reflection please look here :

http://en.csharp-online.net/CSharp_FAQ%3A_How_call_a_method_using_a_name_string

Jason De Oliveira
  • 1,732
  • 9
  • 16