Получение имени вызывающего метода из метода [duplicate]

StackOverflow https://stackoverflow.com/questions/615940

Вопрос

  

Возможный дубликат:
   Как найти метод, который называется текущим метод?

У меня есть метод в объекте, который вызывается из нескольких мест внутри объекта. Есть ли быстрый и простой способ получить имя метода, который вызвал этот популярный метод.

Псевдокод ПРИМЕР:

public Main()
{
     PopularMethod();
}

public ButtonClick(object sender, EventArgs e)
{
     PopularMethod();
}

public Button2Click(object sender, EventArgs e)
{
     PopularMethod();
}

public void PopularMethod()
{
     //Get calling method name
}

В PopularMethod () я бы хотел видеть значение Main , если оно вызывалось из Main ... я хотел бы чтобы увидеть " ButtonClick " если PopularMethod () был вызван из ButtonClick

Я просматривал System.Reflection.MethodBase.GetCurrentMethod () , но это не даст мне вызывающий метод. Я посмотрел на класс StackTrace , но я действительно не наслаждался выполнением трассировки всего стека каждый раз, когда вызывается этот метод.

Это было полезно?

Решение

Я не думаю, что это можно сделать без отслеживания стека. Однако сделать это довольно просто:

StackTrace stackTrace = new StackTrace();
MethodBase methodBase = stackTrace.GetFrame(1).GetMethod();
Console.WriteLine(methodBase.Name); // e.g.

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

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

В .NET 4.5 / C # 5 это просто:

public void PopularMethod([CallerMemberName] string caller = null)
{
     // look at caller
}

компилятор добавляет имя вызывающего автоматически; так:

void Foo() {
    PopularMethod();
}

передается в " Foo " .

Это на самом деле очень просто.

public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod(); // as MethodBase
}

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

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    var currentMethod = System.Reflection.MethodInfo
        .GetCurrentMethod();
}

Чтобы получить вызывающий метод:

[System.Runtime.CompilerServices.MethodImpl(
 System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
public void PopularMethod()
{
    // 1 == skip frames, false = no file info
    var callingMethod = new System.Diagnostics.StackTrace(1, false)
         .GetFrame(0).GetMethod();
}

Просто передайте параметр

public void PopularMethod(object sender)
{

}

ИМО: если этого достаточно для проведения мероприятий, этого должно быть достаточно для этого.

Я часто обнаруживал, что сам желаю это сделать, но всегда заканчивал тем, что реорганизовал дизайн моей системы, поэтому я не получаю это "Хвост, виляющий собакой". анти-модель. Результатом всегда была более надежная архитектура.

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

Я думаю, вам нужно использовать класс StackTrace , а затем StackFrame.GetMethod () в следующем кадре.

Это кажется странной вещью - использовать Reflection . Если вы определяете PopularMethod , вы не можете определить параметр или что-то для передачи информации, которую вы действительно хотите. (Или положить в базовый класс или что-то ...)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top