15

Is it possible to created a method that takes ANY method (regardless of it's parameters) as a parameter? The method would also have a params parameter which then takes all the parameters for the parameter-method.

So basically what I want is something like this:

public void CallTheMethod(Action<int> theMethod, params object[] parameters)

But then for any method, not just for methods that takes an int.

Is something like this possible?

Thanks

The Oddler
  • 6,314
  • 7
  • 51
  • 94
  • 6
    Well, you could pass the non-specific `Delegate`, but `DynamicInvoke` is *sloooooowwwwww* (relatively speaking) – Marc Gravell Aug 20 '13 at 15:00
  • 5
    Just out of curiosity, how would this be more useful than calling the method directly? I must say I'm intrigued though – Kyle G. Aug 20 '13 at 15:00
  • 1
    Out of curiousity, what's the point of this? It seems very error prone. Why not just run the method? – Dennisch Aug 20 '13 at 15:01
  • This *may* be what you want: http://stackoverflow.com/questions/325156/calling-generic-method-with-a-type-argument-known-only-at-execution-time – OnoSendai Aug 20 '13 at 15:02
  • @MarcGravell So it would become public void "CallTheMethodDelegate theMethod, params object[] parameters)"? I know it's slow, but the library I'm using actually asks a string, containing the method name, and a object[], so I thought to make a wrapper so I don't have to manually copy-paste the method names. In case I decide to change the names, so the compiler will tell me if I forgot to change some ^^ – The Oddler Aug 20 '13 at 15:02
  • It is possible, but you need a wrapper lambda. – It'sNotALie. Aug 20 '13 at 15:03
  • 1
    @TheOddler Take a look at http://monotorrent.blogspot.pt/2009/12/yet-another-inotifypropertychanged-with_05.html, you might be able to use Expressions to do what you're after. – RoadieRich Aug 20 '13 at 15:15
  • @RoadieRich Very interesting article. Not what I need for what I'm trying to do now, but still very smart way of doing stuff. Learned something from that :D – The Oddler Aug 20 '13 at 15:21

3 Answers3

8

It's possible, but not what should be done.

This is what I would do:

public void CallTheMethod(Action toCall)

You might go "huh". Basically, what it lets the user do is this:

CallTheMethod(() => SomeOtherMethod(with, some, other, parameters));

However, if you want it to return a type, it involves generics:

public void CallTheMethod<T>(Func<T> theMethod)

You can put generic constraints on that type, do whatever you want with it, etc.

It'sNotALie.
  • 22,289
  • 12
  • 68
  • 103
  • 1
    Very true, what I'm asking doesn't seem like a good thing to do. Though Unity wants the name of a method when calling an RPC. So I though to write a little wrapper, so I don't have to hard-code the method name. Could you also take a look at the comment on Matten's answer? You seem to be very knowledgeable about c#. Thanks! – The Oddler Aug 20 '13 at 16:09
7

Yes, with a delegate:

public object CallTheMethod(Delegate theMethod, params object[] parameters)
{
    return theMethod.DynamicInvoke(parameters);
}

But see Marc Gravell's comment on your question :)

Well, you could pass the non-specific Delegate, but DynamicInvoke is sloooooowwwwww (relatively speaking)

Community
  • 1
  • 1
Matten
  • 17,365
  • 2
  • 42
  • 64
  • 4
    I can't seem to get it to work. I get an error: "Cannot convert from 'method group' to 'System.Delegate'". What I have is a method "DoSomething(int number);" And then your method. So I tried "CallTheMethod(DoSomething, 5)" and then I get the error... Am I doing something wrong, or is there a catch I don't know about? – The Oddler Aug 20 '13 at 15:39
  • I get the same error. I recommend the answere of @itsnotalie. – codekandis Nov 29 '18 at 16:23
3

Yes. You can use DynamicInvoke to call the methods:

Action<int> method1 = i => { };
Func<bool, string> method2 = b => "Hello";

int arg1 = 3;
bool arg2 = true;
//return type is void, so result = null;
object result = method1.DynamicInvoke(arg1);

//result now becomes "Hello";
result = method2.DynamicInvoke(arg2);

A method to do this would become:

object InvokeMyMethod(Delegate method, params object[] args)
{
    return method.DynamicInvoke(args);
}
Bas
  • 26,772
  • 8
  • 53
  • 86