При входе в C #, как я могу узнать имя метода, который вызвал текущий метод? Я знаю все о System.Reflection.MethodBase.GetCurrentMethod()
, но я хочу пойти на шаг ниже в трассировке стека. Я рассмотрел анализ трассировки стека, но я надеюсь найти более понятный и понятный способ, что-то вроде, Assembly.GetCallingAssembly()
кроме методов.
c#
.net
logging
stack-trace
system.diagnostics
flipdoubt
источник
источник
StackTrace
,StackFrame
аCallerMemberName
) и опубликовал результаты как суть для других , чтобы увидеть здесь: gist.github.com/wilson0x4d/7b30c3913e74adf4ad99b09163a57a1fОтветы:
Попробуй это:
один лайнер:
Это из Get Calling Method, использующего Reflection [C #] .
источник
В C # 5 вы можете получить эту информацию, используя информацию о вызывающем абоненте :
Вы также можете получить
[CallerFilePath]
и[CallerLineNumber]
.источник
[CallerTypeName]
был удален из текущей .Net Framework (4.6.2) и Core CLRВы можете использовать информацию о вызывающем абоненте и дополнительные параметры:
Этот тест иллюстрирует это:
В то время как StackTrace работает довольно быстро и выше, и не будет проблемой производительности, в большинстве случаев информация о вызывающем абоненте все еще намного быстрее. В выборке из 1000 итераций я работал в 40 раз быстрее.
источник
CachingHelpers.WhoseThere("wrong name!");
==>,"wrong name!"
потому чтоCallerMemberName
is заменяет только значение по умолчанию.this
параметр в метод расширения. Кроме того, Оливье правильно, вы можете передать значение и[CallerMemberName]
не применяется; вместо этого он работает как переопределение, где обычно используется значение по умолчанию. На самом деле, если мы посмотрим на IL, то увидим, что результирующий метод ничем не отличается от того, который обычно выдается для[opt]
аргумента arg,CallerMemberName
поэтому инъекция - это поведение CLR. Наконец, документы: «Атрибуты Caller Info [...] влияют на значение по умолчанию, которое передается, когда аргумент пропущен »async
дружелюбно, что вамStackFrame
не поможет. Также не влияет на звонки с лямбды.Краткий обзор двух подходов, причем сравнение скорости является важной частью.
http://geekswithblogs.net/BlackRabbitCoder/archive/2013/07/25/c.net-little-wonders-getting-caller-information.aspx
Определение вызывающего во время компиляции
Определение звонящего по стеку
Сравнение 2 подходов
источник
Мы можем немного улучшить код г-на Асада (текущий принятый ответ), создав только тот кадр, который нам нужен, а не весь стек:
Это может работать немного лучше, хотя, по всей вероятности, ему все равно придется использовать полный стек для создания этого единственного кадра. Кроме того, он по-прежнему имеет те же предостережения, на которые указал Алекс Лайман (оптимизатор / собственный код может повредить результаты). Наконец, вы можете захотеть проверить, чтобы быть уверенным в этом
new StackFrame(1)
или.GetFrame(1)
не возвращатьсяnull
, так как маловероятно, что это может показаться.Смотрите этот связанный вопрос: Можете ли вы использовать рефлексию, чтобы найти имя выполняемого в данный момент метода?
источник
new ClassName(…)
равно нулю?В общем, вы можете использовать
System.Diagnostics.StackTrace
класс для полученияSystem.Diagnostics.StackFrame
, а затем использоватьGetMethod()
метод для полученияSystem.Reflection.MethodBase
объекта. Однако есть некоторые предостережения в отношении этого подхода:( ПРИМЕЧАНИЕ: я только расширяю ответ, предоставленный Фирасом Асадом .)
источник
Начиная с .NET 4.5 вы можете использовать атрибуты информации о вызывающем абоненте :
CallerFilePath
- исходный файл, вызвавший функцию;CallerLineNumber
- строка кода, которая вызвала функцию;CallerMemberName
- Член, который вызвал функцию.Эта возможность также присутствует в «.NET Core» и «.NET Standard».
Ссылки
CallerFilePathAttribute
КлассCallerLineNumberAttribute
КлассCallerMemberNameAttribute
Классисточник
Обратите внимание, что это будет ненадежно в коде релиза из-за оптимизации. Кроме того, запуск приложения в режиме «песочницы» (сетевой ресурс) вообще не позволит вам захватить кадр стека.
Рассмотрим аспектно-ориентированное программирование (AOP), такое как PostSharp , которое вместо того, чтобы вызываться из вашего кода, изменяет ваш код и, таким образом, всегда знает, где оно находится.
источник
Очевидно, это поздний ответ, но у меня есть лучший вариант, если вы можете использовать .NET 4.5 или более:
При этом будут напечатаны текущие дата и время, за которыми следует «Namespace.ClassName.MethodName» и заканчивается «: text».
Пример вывода:
Образец использования:
источник
источник
Может быть, вы ищете что-то вроде этого:
источник
Фантастический класс здесь: http://www.csharp411.com/c-get-calling-method/
источник
Другой подход, который я использовал, заключается в добавлении параметра к рассматриваемому методу. Например, вместо
void Foo()
, используйтеvoid Foo(string context)
. Затем передайте некоторую уникальную строку, которая указывает на вызывающий контекст.Если вам нужен только вызывающий / контекст для разработки, вы можете удалить его
param
перед отправкой.источник
Для получения имени метода и имени класса попробуйте это:
источник
будет достаточно, я думаю.
источник
Взгляните на имя метода ведения журнала в .NET . Остерегайтесь использовать его в производственном коде. StackFrame может быть ненадежным ...
источник
Мы также можем использовать лямбду, чтобы найти абонента.
Предположим, у вас есть определенный вами метод:
и вы хотите найти его звонящего.
1 . Измените сигнатуру метода, чтобы у нас был параметр типа Action (Func также будет работать):
2 . Лямбда-имена не генерируются случайным образом. Правило выглядит так:> <CallerMethodName> __ X, где CallerMethodName заменяется предыдущей функцией, а X является индексом.
3 . Когда мы вызываем MethodA, с помощью метода вызывающей стороны должен быть сгенерирован параметр Action / Func. Пример:
4 . Внутри MethodA теперь мы можем вызвать вспомогательную функцию, определенную выше, и найти MethodInfo вызывающего метода.
Пример:
источник
Дополнительная информация к ответу Firas Assaad.
Я использовал
new StackFrame(1).GetMethod().Name;
в ядре .net 2.1 с внедрением зависимостей, и я получаю вызывающий метод как «Пуск».Я пытался с,
[System.Runtime.CompilerServices.CallerMemberName] string callerName = ""
и это дает мне правильный метод вызоваисточник
источник