Подтвердить что ты не робот

Получить имя действия/делегат Func

У меня странная ситуация, когда мне нужно получить имя делегата в виде строки. У меня есть общий метод, который выглядит так.

private T Get<T>(T task, Action<T> method) where T : class
{
  string methodName = method.Method.Name //Should return Bark
}

и я называю это следующим образом

private void MakeDogBark()
{
  dog = Get(dog, x=>x.Bark());
}

Но вместо того, чтобы видеть "Bark", я вижу это "<MakeDogBark>b__19". Таким образом, похоже, что это дает мне имя метода, которое сделало начальный вызов вместо имени делегата.

Кто-нибудь знает, как это сделать?

4b9b3361

Ответ 1

Это дает вам имя метода, который является действием делегата. Это просто происходит с использованием выражения лямбда.

В настоящее время у вас есть делегат, который, в свою очередь, вызывает Bark. Если вы хотите использовать Bark напрямую, вам нужно создать открытый делегат для метода Bark, который может быть не очень простым. Это предполагает, что вы действительно хотите это назвать. Если вам не нужно его вызывать, или вы знаете, что он будет вызываться по первому аргументу, вы можете использовать:

private T Get<T>(T task, Action method) where T : class
{
   string methodName = method.Method.Name //Should return Bark
}

private void MakeDogBark()
{
   dog = Get(dog, dog.Bark);
}

Вы можете обойти это, сделав параметр деревом выражений вместо делегата, но тогда это будет работать, только если выражение лямбда было всего лишь вызовом метода.

Ответ 2

Вы можете получить имя вызова метода, сделав параметр выражением вместо делегата, точно так же, как Джон упомянул

private T Get<T>(T task, Expression<Action<T>> method) where T : class
{
    if (method.Body.NodeType == ExpressionType.Call)
    {
        var info = (MethodCallExpression)method.Body;
        var name = info.Method.Name; // Will return "Bark"
    }

    //.....
}