views:

233

answers:

4

Hello,

I've got a name of a method: "Garden.Plugins.Code.Beta.Business.CalculateRest"

How to run it? I think about this fancy reflection based solution like RunMethod(string MethodName)

+1  A: 

It'll be slow, trust me. So don't put it in a critical place.

Other than that you'll just have to do it "by hand". Start enumerating through all the namespaces, classes, etc. until you find what you need. I don't think there is anything fancy pre-made that does this already. (Although I haven't searched)

Vilx-
Hello, thank you for answer.Yes, it's slow but I need to run a method in this fancy style and try to figure out how to do it. I can't recall but maybe there is something like this.
tomaszs
+3  A: 
  • Split it into type name and method name by splitting on the last dot
  • Get the type using Type.GetType or Assembly.GetType. (Type.GetType will only look in the currently executing assembly and mscorlib, unless you specify the assembly name in the argument.)
  • Get the method from the type using Type.GetMethod. Assuming it's a public static method, specify BindingFlags.Public | BindingFlags.Static.
  • Execute the method by calling MethodInfo.Invoke(null, null). (The first null specifies "no target" - i.e. it's a static method; the second specifies no arguments.)

If you want to call an instance method or one which takes parameters, you'll need to work out how to get that information too.

Jon Skeet
Thank you for answer. So there is no easy way of doing it?
tomaszs
I'd say that three method calls (after the splitting) is pretty easy, to make a dynamic call in a statically typed system. You can very easily encapsulate this in a method. How much easier did you really expect it to be? :)
Jon Skeet
There's a bit more to it if one of the items to the left of the last dot is a inner class. I've posted an answer on how to handle this.
Sean
@Sean: I'd been assuming the type name was the "real" type name. Good call to highlight it though.
Jon Skeet
+1  A: 

If the type is an instance type:

Type.GetType("Garden.Plugins.Code.Beta.Business")
    .GetMethod("CalculateRest").Invoke(myInstanceOfTheType, param1, param2);

If it's a static method:

Type.GetType("Garden.Plugins.Code.Beta.Business")
    .GetMethod("CalculateRest").Invoke(null, param1, param2);

If it doesn't take parameters, just leave off "param1, param2, etc"...

Timothy Khouri
+2  A: 

It's not quite as simple as treating everything to the left of the last dot as the literal typename. If you've got a type of the form:

X.Y.Z.Type

then it's not necessarily the case that X, Y and Z are namespaces. They could also be types themselves and the subsequent parts could be inner classes:

class X
{
  class Y
  {
   // etc
  }
}

If this is the case then Type.GetType("X.YU") wont resolve to the Y class.Instead, the clr seperates inner classes with a + symbol, so you'd actually need to call Type.GetType("X+Y");

If the method that you're calling is a params method then you'll need to so some additional work. You're required to roll the variable parameters up into an array and pass this. You can check for variable parameters by grabbing the ParameterInfo data for a method and seeing if the last parameter has the ParamArray attribute attached.

Sean