Есть ли способ получить имя метода динамически в C#?
У меня есть случай, когда я передаю имя метода функции в виде строки, но я не хочу, чтобы оно было жестко запрограммировано. например
void MyMethodName()
{
// some code
}
void SomeOtherMethod()
{
SomeExternalLibrary.ExternalClass.FunctionWithStringParameter("MyMethodName");
}
Я хочу что-то вроде этого:
FunctionWithStringParameter(MyMethodName.ToString());
Таким образом, я могу отслеживать вызовы методов с помощью "Найти все ссылки", и я могу использовать рефакторинг без забот.
3 ответа
Возможно, самым простым способом было бы обеспечить перегрузку FunctionWithStringParameter
который может принимать делегата в качестве параметра.
Перегрузка может быть такой простой, как:
void FunctionWithStringParameter(Action d)
{
FunctionWithStringParameter(d.Method.Name);
}
И назовите это так:
FunctionWithStringParameter(MyMethodName);
Чтобы принимать методы с разными сигнатурами, вам придется либо предоставить много разных перегрузок, либо принять Delegate
как параметр, вот так:
void FunctionWithStringParameter(Delegate d)
{
FunctionWithStringParameter(d.Method.Name);
}
К сожалению, если вы сделаете это, вам придется вызвать его, указав тип делегата:
FunctionWithStringParameter((Action)MyMethodName);
Одна из техник, которая часто используется в эти дни, это пройти Expression
,
FunctionWithStringParameter(x => MyMethodName(x));
Внутри вашего метода вы можете выделить выражение, чтобы получить имя вызываемого метода (и проверить, что это простое выражение вызова метода).
См. Раздел Получение имени свойства из лямбда-выражения, чтобы узнать, как разделить лямбда-выражение.
Я не уверен, что вы пытаетесь сделать, но один из способов избежать "волшебных строк" при обращении к методам и свойствам - это делать то, что делают методы ASP.NET MVC Helpers, которые выглядят так:
@Html.TextBoxFor(m=> m.SomeProperty)
и сделать какой-то помощник, который позволяет вам сделать:
string methodName = ReflectionHelper.MethodNameFor<TheTypeWIthTheMethod>(x=> x.TheMethod())
Реализация будет выглядеть примерно так:
static string MethodNameFor<T>(Expression<Action<T>> expression)
{
return ((MethodCallExpression)expression.Body).Method.Name;
}