Получение имени вызывающего метода из метода [duplicate]
-
03-07-2019 - |
Вопрос
Возможный дубликат:
Как найти метод, который называется текущим метод?
У меня есть метод в объекте, который вызывается из нескольких мест внутри объекта. Есть ли быстрый и простой способ получить имя метода, который вызвал этот популярный метод.
Псевдокод ПРИМЕР:
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
, вы не можете определить параметр или что-то для передачи информации, которую вы действительно хотите. (Или положить в базовый класс или что-то ...)