Есть ли способ получить имя метода динамически в 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;
 }
Другие вопросы по тегам