Как я могу узнать, какой метод вызывает мой метод? - PullRequest
3 голосов
/ 05 июля 2010

У меня есть 3 метода A (), B () и C (), оба A () и B () вызывают C ().В методе C (), как я могу знать, что это вызов из A () или B ()?

Ответы [ 9 ]

11 голосов
/ 05 июля 2010

Тебе не нужно это делать. Какой-то метод должен выполнять определенную задачу, на которую влияют его параметры и атрибуты объекта, а не вызывающая сторона.

8 голосов
/ 05 июля 2010

Я не рекомендую такой подход - другие авторы указывают на лучшие способы справиться с этим. Но если вам действительно нужно знать, кто вам звонил, без изменения параметров C(), вы можете сделать это:

static void A()
{
    C();
}

static void C()
{
    StackTrace st = new StackTrace();
    Console.WriteLine(st.GetFrame(1).GetMethod().Name); // prints "A"
}

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

Опять же, вы почти наверняка найдете лучший способ сделать то, что вы пытаетесь сделать.

3 голосов
/ 05 июля 2010

Метод C () не должен нуждаться в , чтобы знать, какой метод вызвал его. Если именно так вы обрабатываете свою логику потока, вам нужно еще раз подумать о том, как вы пишете свой код. Если предположить, что есть веская причина для необходимости знать, какой метод называется C (), я бы создал два метода-обертки: C_From_A () и C_From_B (). Любая логика, специфичная для вызывающих методов, должна быть перемещена в новые методы, в то время как общий код оставлен в методе C () и вызван из обоих новых методов:

public void C()
{
   // Common Code goes here
}

public void C_From_A()
{
    // Code only to be called from A() goes here.

    C();  // Common code executed
}

public void C_From_B()
{
    // Code only to be called from B() goes here.

    C();  // Common code executed
}


public void A()
{
    // Other code goes here

    C_From_A();
}

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

2 голосов
/ 05 июля 2010

Вы должны взглянуть на System.Diagnostics.StackFrame класс.Пример здесь: http://www.csharp -examples.net / отражение-callstack /

1 голос
/ 05 июля 2010

Простой (и понятный) способ - ввести новый параметр для C и позволить A и B сообщить C, кто его вызвал.

0 голосов
/ 05 июля 2010
MethodBase callerMethod = new System.Diagnostics.StackFrame(1).GetMethod();

Полезно, если вы пишете структуру аудита / журнала, но на самом деле здесь применяется YDNTN.Плюс это стоит целое состояние во время выполнения.

0 голосов
/ 05 июля 2010

В случае, когда вы пытаетесь выяснить, где был передан «неверный параметр», вам нужно всего лишь установить условную точку останова в этом методе или иметь разрыв VS для исключения, которое будет выброшено, а затем вы можете проверить стек вызовов (меню отладки, окно, стек вызовов), чтобы увидеть всю цепочку вызывающих (с переданными аргументами) для этого метода.

0 голосов
/ 05 июля 2010

Я согласен в принципе, вам не нужно знать в большинстве ситуаций.

Однако, один из случаев, когда это может быть полезно знать, - это при отладке, откуда пришла определенная информация, в случае передачи неверного параметра.

Однако в этом случае, вероятно, лучше создать исключение, зарегистрировать исключение и «восстановить» его. Очевидно, это зависит от того, как часто вызывается метод, поскольку при создании исключения всегда есть некоторые накладные расходы. Если вам нужно сделать это по какой-то другой причине, чем я бы посоветовал вам сначала посмотреть на свой дизайн.

Если вам нужны обратные вызовы, я бы посоветовал вам сделать так, чтобы A и B реализовывали интерфейс и передавали A или B в качестве параметра. Интерфейс может иметь метод обратного вызова, а C может вызывать A или B.

0 голосов
/ 05 июля 2010

Просто установите точку останова в C ()

...