Как и в заголовке: «Может ли отражение дать вам имя выполняемого в настоящее время метода».
Я склонен не догадываться из-за проблемы Гейзенберга. Как вы вызываете метод, который скажет вам текущий метод, не меняя, какой текущий метод? Но я надеюсь, что кто-то может доказать, что я ошибаюсь там.
Обновить:
- Часть 2: Может ли это быть использовано для поиска в коде свойства?
- Часть 3: Каким будет представление?
Окончательный результат
я узнал о MethodBase.GetCurrentMethod (). Я также узнал, что я могу не только создавать трассировку стека, но и создавать только тот кадр, который мне нужен, если я хочу.
Чтобы использовать это внутри свойства, просто возьмите .Substring (4), чтобы удалить 'set_' или 'get_'.
.net
reflection
Джоэл Коухорн
источник
источник
Ответы:
Начиная с .NET 4.5 вы также можете использовать [CallerMemberName]
Пример: установщик свойства (для ответа на часть 2):
Компилятор будет предоставлять совпадающие строковые литералы на сайтах вызовов, так что в основном это не влияет на производительность.
источник
StackFrame(1)
метод, описанный в других ответах, для регистрации, который, казалось, работал, пока Джиттер не решил начать встраивать вещи. Я не хотел добавлять атрибут для предотвращения встраивания по соображениям производительности. Использование[CallerMemberName]
подхода решило проблему. Спасибо!OnPropertyChanged("SomeProperty")
а не к немуOnPropertyChanged("SetProperty")
Для не-
async
методов можно использоватьhttps://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.getcurrentmethod
Пожалуйста, помните, что для
async
методов он вернет «MoveNext».источник
async
метода вы, скорее всего, получите «MoveNext» в качестве имени метода.Фрагмент, предоставленный Лексом, был немного длинным, поэтому я указываю на важную часть, поскольку никто другой не использовал точно такую же технику:
Это должно вернуть идентичные результаты для метода MethodBase.GetCurrentMethod (). Name , но на это все же стоит обратить внимание, потому что я мог бы реализовать это один раз в своем собственном методе, используя индекс 1 для предыдущего метода, и вызывать его из ряда различных свойств. Кроме того, он возвращает только один кадр вместо всей трассировки стека:
Это тоже одна строка;)
источник
Попробуйте это внутри метода Main в пустой консольной программе:
Консольный вывод:
Main
источник
Определенно да.
Если вы хотите, чтобы объект манипулировал, я на самом деле использую такую функцию:
Эта строка:
Идет вверх по стековому фрейму, чтобы найти вызывающий метод, затем мы используем отражение, чтобы получить значения информации о параметрах, переданные ему для общей функции сообщения об ошибках. Чтобы получить текущий метод, просто используйте вместо этого текущий стек (1).
Как уже говорили другие для имени текущего метода, вы также можете использовать:
Я предпочитаю ходить по стеку, потому что если взглянуть внутренне на этот метод, он все равно просто создает StackCrawlMark. Обращение к стеку мне кажется более понятным
После 4.5 вы можете теперь использовать [CallerMemberNameAttribute] как часть параметров метода, чтобы получить строку с именем метода - это может помочь в некоторых сценариях (но на самом деле, скажем, в примере выше)
Похоже, что это в основном решение для поддержки INotifyPropertyChanged, где ранее у вас были строки, засоренные на протяжении всего кода события.
источник
Сравнение способов получения имени метода - используя произвольную временную конструкцию в LinqPad:
КОД
ПОЛУЧЕННЫЕ РЕЗУЛЬТАТЫ
отражение отражение
стек трассировки стек трассировки
inlineconstant inlineconstant
постоянная константа
expr e => e.expr ()
exprmember exprmember
callermember Главная
Обратите внимание , что
expr
иcallermember
методы не совсем «правильно». И там вы видите повторение связанного комментария о том, что отражение в ~ 15 раз быстрее, чем трассировка стека.источник
РЕДАКТИРОВАТЬ: MethodBase, вероятно, лучший способ просто получить метод, в котором вы находитесь (в отличие от всего стека вызовов). Я все еще был бы обеспокоен по поводу встраивания однако.
Вы можете использовать StackTrace в методе:
И посмотрите на кадры:
Тем не менее, имейте в виду, что если метод встроен, вы не окажетесь внутри того метода, который вам кажется. Вы можете использовать атрибут для предотвращения встраивания:
источник
new StackTrace(true)
вместоnew StackTrace(false)
. Установка этого параметраtrue
приведет к тому, что трассировка стека попытается захватить имя файла, номер строки и т. Д., Что может замедлить этот вызов. Иначе хороший ответПростой способ разобраться:
Если System.Reflection включен в блок using:
источник
Как насчет этого:
источник
Я думаю, вы сможете получить это от создания StackTrace . Или, как упоминают @ edg и @ Lars Mæhlum , MethodBase. GetCurrentMethod ()
источник
Попробуй это...
источник
Я просто сделал это с помощью простого статического класса:
тогда в вашем коде:
источник
источник