1

how do you call a method based on the contents of a variable

ex.

String S = "Hello World";
String Format = "ToUpper()";

String sFormat = s.Format;

resulting in "HELLO WORLD"

This way I could at some other time pass Format = "ToLower()" or Format = "Remove(1,4)" which will delete 4 characters starting from pos 1 - in short I would like the ability to call any string method.

Could someone post a complete working solution.

wadapav
  • 107
  • 5
  • 14
  • You could do this easily with reflection... but it wouldn't exactly be the fastest bit of code ever written. – asawyer Jul 24 '12 at 02:52
  • see this answer: http://stackoverflow.com/questions/4629/how-can-i-read-the-properties-of-a-c-sharp-class-dynamically – David Jul 24 '12 at 02:57
  • 1
    The real question is; is this the best way to solve your problem? – Ed S. Jul 24 '12 at 03:01
  • ...and how (or in what scenario) actually it's helping you?! – atiyar Jul 24 '12 at 03:25
  • Hi, and welcome to SO! "_post a complete working solution_" is not something we are in the _general_ habit of doing around here, but we're happy to help you along and give you hints. Do you have an example or a snippet of code you're having any particular trouble with? – J. Steen Jul 24 '12 at 13:20

6 Answers6

1

The crux of the solution requires you to use Reflection to locate the required method. This is a simple example covering your sitaution;

private string DoFormat(string data, string format)
{
    MethodInfo mi = typeof (string).GetMethod(format, new Type[0]);
    if (null == mi)
        throw new Exception(String.Format("Could not find method with name '{0}'", format));

    return mi.Invoke(data, null).ToString();
}

You can make the method more generic, to accept arguments to the method you want to call, as below. Note the change to the way .GetMethod and .Invoke are called to pass the required arguments.

private static string DoFormat(string data, string format, object[] parameters)
{
    Type[] parameterTypes = (from p in parameters select p.GetType()).ToArray();

    MethodInfo mi = typeof(string).GetMethod(format, parameterTypes);
    if (null == mi)
        throw new Exception(String.Format("Could not find method with name '{0}'", format));

    return mi.Invoke(data, parameters).ToString();
}
RJ Lohan
  • 6,497
  • 3
  • 34
  • 54
  • Your solution works fine for ToUpper or ToLower but how do I pass Replace(1,4) – wadapav Jul 24 '12 at 14:58
  • See edits above. You need to call different overloads of GetMethod and Invoke to pass arguments to the'DoFormat' method. – RJ Lohan Jul 24 '12 at 21:59
1

You can do this with reflection, but the code becomes hard to read, and type safety disappears.

C# provides a much better mechanism for passing executable code around - namely, the delegates.

You can do something like this:

void ShowConverted(string str, Func<string,string> conv) {
    Console.WriteLine("{0} -- {1}", str, conv(str));
}

Func<string,string> strAction1 = (s) => s.ToUpper();
Func<string,string> strAction2 = (s) => s.ToLower();
ShowConverted("Hello, world!", stringAction1);
ShowConverted("Hello, world!", stringAction2);
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

You can use reflection to pull the ToLower() method from the string type.

  string format = "Hello World";
  MethodInfo methodInfo = typeof(string).GetMethod("ToLower");
  string result = methodInfo.Invoke(format,null);

I may have messed up the syntax a little

TheJediCowboy
  • 8,924
  • 28
  • 136
  • 208
0

Why not just use the methods themselves.

Func<string, string> format = s = > s.ToUpper();

and then you could do

format = s = > s.ToLower();

Otherwise you'd have to go with Reflection, which isn't safe and likely slower.

Yuriy Faktorovich
  • 67,283
  • 14
  • 105
  • 142
0

You could make use of Reflection here. Take a look at MethodInfo class.

danish
  • 5,550
  • 2
  • 25
  • 28
0

Something like this would work, but I don't have a compiler in front of me to verify.

Use it like:

var result = someObject.CallParameterlessMethod("ToUpper");




public static class ObjectExtensionMethods
{
  public static object CallParameterlessMethod(this object obj, string methodName)
  {
    var method = typeof(obj).GetMethod(methodName);
    return method.Invoke(obj,null);
  }
}
asawyer
  • 17,642
  • 8
  • 59
  • 87