37

I have a method:

  add(int x,int y)

I also have:

int a = 5;
int b = 6;
string s = "add";

Is it possible to call add(a,b) using the string s?

kingsfoil
  • 3,795
  • 7
  • 32
  • 56
scatman
  • 14,109
  • 22
  • 70
  • 93

5 Answers5

73

how can i do this in c#?

Using reflection.

add has to be a member of some type, so (cutting out a lot of detail):

typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2})

This assumes add is static (otherwise first argument to Invoke is the object) and I don't need extra parameters to uniquely identify the method in the GetMethod call.

Richard
  • 106,783
  • 21
  • 203
  • 265
  • 2
    @DavidStratton It will work with `private` members: use one of the overloads of [`GetMethod`](http://msdn.microsoft.com/en-us/library/05eey4y9.aspx) that takes a [`BindingFlags`](http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx) argument with `BindingFlags.NonPublic`. – Richard Sep 23 '11 at 17:05
  • 2
    Can we use "Func<>" instead of Refection ? – Sreekumar P Aug 13 '12 at 11:38
  • 1
    @Sreekumar No, because to create a lambda you either need to fix at compile time or build expression trees. The latter done dynamically will need to use reflection. – Richard Aug 13 '12 at 12:05
25

Use reflection - try the Type.GetMethod Method

Something like

MethodInfo addMethod = this.GetType().GetMethod("add");
object result = addMethod.Invoke(this, new object[] { x, y } );

You lose strong typing and compile-time checking - invoke doesn't know how many parameters the method expects, and what their types are and what the actual type of the return value is. So things could fail at runtime if you don't get it right.

It's also slower.

Anthony
  • 5,176
  • 6
  • 65
  • 87
17

If the functions are known at compile time and you just want to avoid writing a switch statement.

Setup:

Dictionary<string, Func<int, int, int>> functions =
  new Dictionary<string, Func<int, int, int>>();

functions["add"] = this.add;
functions["subtract"] = this.subtract;

Called by:

string functionName = "add";
int x = 1;
int y = 2;

int z = functions[functionName](x, y);
Amy B
  • 108,202
  • 21
  • 135
  • 185
11

You can use reflection.

using System;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Program p = new Program();
            Type t = p.GetType();
            MethodInfo mi = t.GetMethod("add", BindingFlags.NonPublic | BindingFlags.Instance);
            string result = mi.Invoke(p, new object[] {4, 5}).ToString();
            Console.WriteLine("Result = " + result);
            Console.ReadLine();
        }

        private int add(int x, int y)
        {
            return x + y;
        }
    }
}
Itay Karo
  • 17,924
  • 4
  • 40
  • 58
0

@Richard's answer is great. Just to expand it a bit:

This can be useful in a situation where you dynamically created an object of unknown type and need to call its method:

var do = xs.Deserialize(new XmlTextReader(ms)); // example - XML deserialization
do.GetType().GetMethod("myMethodName").Invoke(do, new [] {arg1, arg2});

becasue at compile time do is just an Object.

ajeh
  • 2,652
  • 2
  • 34
  • 65