Учитывая метод, который принимает метод в качестве входных данных, получает его класс и имя метода

Мне было интересно, можно ли получить метод и имя класса введенной функции метода. Я постараюсь быть более конкретным:

У меня есть класс Form1.cs, в котором я создал этот метод:

public static void CalculateTime(Action<string> funcToCalc, string where)
        {
            var watch = System.Diagnostics.Stopwatch.StartNew();

            funcToCalc(where);

            watch.Stop();
            var elapsedMs = watch.ElapsedMilliseconds;
            // gets the textbox name
            TextBox t = Application.OpenForms["Form1"].Controls["textBox1"] as TextBox;
            // writes in the textbox of this form this string
            t.AppendText(funcToCalc.Method.Name + " executed in " + elapsedMs + "ms;\n");

        }

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

CalculateTime( Class1.CreateStuff, textPath.Text);
CalculateTime( Class2.CreateStuff, textPath.Text);

Я хочу распечатать что-то вроде

"MyClass1.CreateStuff executed in 100ms"
"MyClass2.CreateStuff executed in 75ms"

и т.п.

На данный момент мой метод распечатывает

"CreateStuff executed in 100ms"
"CreateStuff executed in 75ms"

что не позволяет мне распознать класс вызываемого метода.

Есть ли способ получить имя класса в этом конкретном случае?

Обратите внимание, что если в моем CalculateTime я звоню

System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name;

Я получаю строку "Form1".

Какой класс вы ожидаете для единодушных действий?

Tim 25.06.2019 10:51

Вызов System.Reflection.MethodBase.GetCurrentMethod().DeclaringTyp‌​e.Name; из формы form1, конечно же, вернет form1..

BugFinder 25.06.2019 10:52

Мне просто интересно, возможно ли это без передачи параметров методу

Don Diego 25.06.2019 10:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
39
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Самый простой способ — запросить свойство делегата Method, которое указывает на выполняемый метод.

Обратите внимание, что, хотя он работает для статических членов и членов экземпляра, он не обязательно имеет смысл при вызове анонимного делегата (когда возвращается бессмысленное имя метода, созданного компилятором):

using System;

public class Foo1
{
  // static
  public static void Method( string s )
  {
  } 
}
public class Foo2
{
  // instance
  public void Method( string s )
  {
  }
}

public class Program
{
  public static void  Main(string[] args)
  {
    PrintDelegateInfo( Foo1.Method );
    PrintDelegateInfo( new Foo2().Method );
    PrintDelegateInfo( (Action<string>)(s => {}) );
  }

  private static void PrintDelegateInfo(Action<string> funcToCall)
  {
    var methodInfo = funcToCall.Method;
    var name = string.Format( "{0}.{1}", methodInfo.DeclaringType.Name, methodInfo.Name );

    Console.WriteLine( "{0} called", name );
  }
}

Выход:

Foo1.Method called
Foo2.Method called
Program.<Main>b__0 called

Вы можете использовать в самом действии метод расширения GetMethodInfo(Delegate), чтобы получить MethodInfo для делегата. Предполагая, что вы не передаете анонимный типизированный делегат, такой как функция Lambda, вы можете использовать этот MethodInfo для получения типа класса с помощью DeclaringType следующим образом:

public static void CalculateTime(Action<string> funcToCalc, string where)
    {   
        var miAction = funcToCalc.GetMethodInfo();
        var actionContainingType = miAction.DeclaringType;
        var watch = System.Diagnostics.Stopwatch.StartNew();

        funcToCalc(where);

        watch.Stop();
        var elapsedMs = watch.ElapsedMilliseconds;
        // gets the textbox name
        TextBox t = Application.OpenForms["Form1"].Controls["textBox1"] as TextBox;
        // writes in the textbox of this form this string
        t.AppendText($"{actionContainingType.Name}.{funcToCalc.Method.Name} executed in {elapsedMs} ms;\n");

    }

Другие вопросы по теме