Как я могу найти метод, который вызвал текущий метод?

445
задан Shaun Wilson 17 March 2018 в 18:15
поделиться

8 ответов

Попробуйте это:

using System.Diagnostics;
// Get call stack
StackTrace stackTrace = new StackTrace();

// Get calling method name
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name);

Это от , Получают Вызывающий метод с помощью Отражательного [C#].

453
ответ дан Peter Mortensen 17 March 2018 в 18:15
поделиться
  • 1
    Та же проблема здесь - это добавило шесть дополнительных наклонных черт к каждому концу пути. В другом проекте я добавил несколько платформ к " Свяжите Двоичный файл С Libraries" Фаза разработки и это добавили дополнительную наклонную черту к каждому пути. Заставляет меня думать, что я схожу с ума - все работа и внезапно не работа! Я заканчиваю тем, что вошел в сам pbxproj файл для исправления путей. – GTAE86 11 October 2013 в 16:20

Другой подход, который я использовал, должен добавить параметр к рассматриваемому методу. Например, вместо void Foo(), используйте void Foo(string context). Тогда передача в некоторой уникальной строке, которая указывает на контекст вызова.

, Если Вам только нужна вызывающая сторона/контекст для разработки, можно удалить param перед поставкой.

2
ответ дан Irshad 17 March 2018 в 18:15
поделиться

Смотрите на Регистрирующееся имя метода в.NET . Остерегайтесь использования его в производственном коде. StackFrame не может быть надежным...

1
ответ дан Peter Mortensen 17 March 2018 в 18:15
поделиться

Обратите внимание, что выполнение так будет ненадежно в коде выпуска, из-за оптимизации. Кроме того, запуск приложения в режиме песочницы (сетевой ресурс) не позволит Вам захватывать стековый фрейм вообще.

Рассматривают аспектно-ориентированное программирование (AOP), как PostSharp, который вместо того, чтобы быть названным от Вашего кода, изменяет Ваш код, и таким образом знает, где это в любом случае.

14
ответ дан guneysus 17 March 2018 в 18:15
поделиться

Возможно, Вы ищете что-то вроде этого:

StackFrame frame = new StackFrame(1);
frame.GetMethod().Name; //Gets the current method name

MethodBase method = frame.GetMethod();
method.DeclaringType.Name //Gets the current class name
6
ответ дан jesal 17 March 2018 в 18:15
поделиться

В целом можно использовать System.Diagnostics.StackTrace класс, чтобы добраться System.Diagnostics.StackFrame , и затем использовать GetMethod() метод для получения System.Reflection.MethodBase объект. Однако существуют некоторые протесты к этому подходу:

  1. Это представляет время выполнения стек - оптимизация могла встроить метод, и Вы будете не , посмотрите что метод в отслеживании стека.
  2. Это будет не шоу любые собственные кадры, поэтому если будет даже шанс, которым Ваш метод называет собственный метод, это будет не работа, и нет на самом деле никакого в настоящее время доступного способа сделать это.

( ПРИМЕЧАНИЕ: Я просто подробно останавливаюсь ответ обеспеченный Firas Assad .)

60
ответ дан Community 17 March 2018 в 18:15
поделиться

Мы можем изменить к лучшему код г-на Assad (текущий принятый ответ) просто немного путем инстанцирования только кадра, в котором мы на самом деле нуждаемся, а не весь стек:

new StackFrame(1).GetMethod().Name;

Это могло бы работать немного лучше, хотя, по всей вероятности, это все еще должно использовать полный стек для создания того единственного кадра. Кроме того, это все еще имеет те же протесты, что Alex Lyman указал (оптимизатор/собственный код мог бы повредить результаты). Наконец, Вы могли бы хотеть проверить, чтобы быть уверенными, что new StackFrame(1) или .GetFrame(1) не возвращаются null, настолько вряд ли, как та возможность могла бы казаться.

Посмотрите этот связанный вопрос: можно ли использовать отражение для нахождения названия в настоящее время метода выполнения?

61
ответ дан Community 17 March 2018 в 18:15
поделиться
/// <summary>
/// Returns the call that occurred just before the "GetCallingMethod".
/// </summary>
public static string GetCallingMethod()
{
   return GetCallingMethod("GetCallingMethod");
}

/// <summary>
/// Returns the call that occurred just before the the method specified.
/// </summary>
/// <param name="MethodAfter">The named method to see what happened just before it was called. (case sensitive)</param>
/// <returns>The method name.</returns>
public static string GetCallingMethod(string MethodAfter)
{
   string str = "";
   try
   {
      StackTrace st = new StackTrace();
      StackFrame[] frames = st.GetFrames();
      for (int i = 0; i < st.FrameCount - 1; i++)
      {
         if (frames[i].GetMethod().Name.Equals(MethodAfter))
         {
            if (!frames[i + 1].GetMethod().Name.Equals(MethodAfter)) // ignores overloaded methods.
            {
               str = frames[i + 1].GetMethod().ReflectedType.FullName + "." + frames[i + 1].GetMethod().Name;
               break;
            }
         }
      }
   }
   catch (Exception) { ; }
   return str;
}
8
ответ дан 22 November 2019 в 22:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: