3

I have a case where I pass a method name to a function as a string, but I don't want it hard-coded. for example

void MyMethodName()
{
    // some code
}

void SomeOtherMethod()
{
    SomeExternalLibrary.ExternalClass.FunctionWithStringParameter("MyMethodName");
}

I want something like this:

FunctionWithStringParameter(MyMethodName.ToString());

THis way I can keep track of method calls by "Find All References", and I can use refactoring without worries.

Esam Bustaty
  • 346
  • 1
  • 4
  • 13
  • http://stackoverflow.com/questions/2968352/using-system-reflection-to-get-a-methods-full-name Might help. That said if you don't want to use reflection - you could always set the string as a public const. – Haedrian Dec 07 '13 at 20:48
  • 3
    What is your reason for passing the method name? Do you then invoke the method by looking it up by name? Instead, try using a delegate or lambda expression. – John Saunders Dec 07 '13 at 20:49
  • I believe you're trying to solve the wrong problem. If you need better refactoring support, you should use a tool like [ReSharper](http://www.jetbrains.com/resharper/) to help you rename and navigate code beyond what Visual Studio is capable of. – Igal Tabachnik Dec 07 '13 at 20:52
  • I have this issue with Unity3D, It has an "Invoke" method that invokes a function after an interval, I can't replace it for many reasons, to make things short it's part of the ecosystem and I'm not going to change nature... – Esam Bustaty Dec 07 '13 at 21:07

3 Answers3

5

Perhaps the easiest way would be to provide an overload FunctionWithStringParameter which can take a delegate as a parameter.

The overload could be as simple as:

void FunctionWithStringParameter(Action d)
{
    FunctionWithStringParameter(d.Method.Name);
} 

And call it like this:

FunctionWithStringParameter(MyMethodName);

To accept methods with different signatures, you'd have to either provide many different overloads, or accept Delegate as a parameter, like this:

void FunctionWithStringParameter(Delegate d)
{
    FunctionWithStringParameter(d.Method.Name);
} 

Unfortunately, if you do this, you would have to call it by specifying a delegate type:

FunctionWithStringParameter((Action)MyMethodName);
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
2

One technique used a lot these days is to pass an Expression.

FunctionWithStringParameter(x => MyMethodName(x));

Inside your method you can pick the expression apart to get the method name being called (and check that it is a simple method call expression).

See Retrieving Property name from lambda expression for ideas on how to pick apart the lambda expression.

Community
  • 1
  • 1
Ian Mercer
  • 38,490
  • 8
  • 97
  • 133
0

I'm not sure what you are trying to do, but one way to avoid "magic strings" when referencing methods and properties is do do what the ASP.NET MVC Helpers methods do that look like this :

@Html.TextBoxFor(m=> m.SomeProperty)

and do some kind of helper that allows you to do :

string methodName = ReflectionHelper.MethodNameFor<TheTypeWIthTheMethod>(x=> x.TheMethod())

The implementation would look something like that :

static string MethodNameFor<T>(Expression<Action<T>> expression)
 {
        return ((MethodCallExpression)expression.Body).Method.Name;
 }
tsimbalar
  • 5,790
  • 6
  • 37
  • 61