Seperti judulnya katakan: Dapatkah refleksi memberi Anda nama metode yang sedang dijalankan.
Saya cenderung tidak menebak, karena masalah Heisenberg. Bagaimana Anda memanggil metode yang akan memberi tahu Anda metode saat ini tanpa mengubah apa metode saat ini? Tapi saya berharap seseorang bisa membuktikan saya salah di sana.
Memperbarui:
- Bagian 2: Bisakah ini digunakan untuk mencari kode di dalam properti juga?
- Bagian 3: Seperti apa performanya?
Hasil Akhir yang
saya pelajari tentang MethodBase.GetCurrentMethod (). Saya juga belajar bahwa saya tidak hanya dapat membuat jejak stack, saya hanya dapat membuat frame persis yang saya butuhkan jika saya mau.
Untuk menggunakan ini di dalam properti, cukup ambil. Substring (4) untuk menghapus 'set_' atau 'get_'.
.net
reflection
Joel Coehoorn
sumber
sumber
Jawaban:
Pada .NET 4.5 Anda juga dapat menggunakan [CallerMemberName]
Contoh: penyetel properti (untuk menjawab bagian 2):
Compiler akan menyediakan string literal yang cocok di callsites, jadi pada dasarnya tidak ada overhead kinerja.
sumber
StackFrame(1)
metode yang dijelaskan dalam jawaban lain untuk penebangan, yang tampaknya bekerja sampai Jitter memutuskan untuk mulai menyelaraskan berbagai hal. Saya tidak ingin menambahkan atribut untuk mencegah inlining karena alasan kinerja. Menggunakan[CallerMemberName]
pendekatan memperbaiki masalah. Terima kasih!OnPropertyChanged("SomeProperty")
dan tidakOnPropertyChanged("SetProperty")
Untuk non-
async
metode, seseorang dapat menggunakanhttps://docs.microsoft.com/en-us/dotnet/api/system.reflection.methodbase.getcurrentmethod
Harap diingat bahwa untuk
async
metode ini akan mengembalikan "MoveNext".sumber
async
Metode di dalam Anda kemungkinan besar akan mendapatkan "MoveNext" sebagai nama metode.Cuplikan yang disediakan oleh Lex agak panjang, jadi saya menunjukkan bagian penting karena tidak ada orang lain yang menggunakan teknik yang sama persis:
Ini harus mengembalikan hasil yang identik ke MethodBase.GetCurrentMethod (). Teknik nama , tapi masih layak untuk ditunjukkan karena saya bisa menerapkan ini sekali dalam metode sendiri menggunakan indeks 1 untuk metode sebelumnya dan memanggilnya dari sejumlah properti yang berbeda. Selain itu, ia hanya mengembalikan satu frame ketimbang seluruh jejak tumpukan:
Ini juga satu kalimat;)
sumber
Coba ini di dalam metode Utama di program konsol kosong:
Output Konsol:
Main
sumber
Iya tentu saja.
Jika Anda ingin memanipulasi objek, saya sebenarnya menggunakan fungsi seperti ini:
Garis ini:
Menaiki bingkai tumpukan untuk menemukan metode pemanggilan kemudian kami menggunakan refleksi untuk mendapatkan nilai informasi parameter yang diteruskan ke sana untuk fungsi pelaporan kesalahan umum. Untuk mendapatkan metode saat ini, cukup gunakan bingkai tumpukan saat ini (1).
Seperti yang orang lain katakan untuk nama metode saat ini, Anda juga dapat menggunakan:
Saya lebih suka berjalan stack karena jika melihat secara internal pada metode itu hanya menciptakan StackCrawlMark. Mengatasi Stack secara langsung tampak lebih jelas bagi saya
Posting 4.5 Anda sekarang dapat menggunakan [CallerMemberNameAttribute] sebagai bagian dari parameter metode untuk mendapatkan string dari nama metode - ini dapat membantu dalam beberapa skenario (tetapi benar-benar mengatakan contoh di atas)
Ini tampaknya terutama solusi untuk dukungan INotifyPropertyChanged di mana sebelumnya Anda memiliki string yang berserakan di seluruh kode acara Anda.
sumber
Membandingkan cara untuk mendapatkan nama metode - menggunakan konstruk pewaktuan arbitrer di LinqPad:
KODE
HASIL
refleksi refleksi
stacktrace stacktrace
inlineconstant inlineconstant
konstan konstan
expr e => e.expr ()
exprmember exprmember
callermember Main
Perhatikan bahwa
expr
dancallermember
metode tidak "benar". Dan di sana Anda melihat pengulangan dari komentar terkait bahwa refleksi ~ 15x lebih cepat dari stacktrace.sumber
EDIT: MethodBase mungkin merupakan cara yang lebih baik untuk mendapatkan metode yang Anda gunakan (sebagai lawan dari keseluruhan tumpukan panggilan). Saya masih khawatir tentang inlining.
Anda dapat menggunakan StackTrace dalam metode:
Dan lihat pada bingkai:
Namun, ketahuilah bahwa jika metode ini sebaris, Anda tidak akan berada di dalam metode yang Anda pikirkan. Anda bisa menggunakan atribut untuk mencegah inlining:
sumber
new StackTrace(true)
bukannew StackTrace(false)
. Menyetel ke manatrue
akan menyebabkan tumpukan jejak untuk mencoba menangkap nama file, nomor baris dan lain-lain, yang mungkin membuat panggilan ini lebih lambat. Jika tidak, jawaban yang bagusCara sederhana untuk bertransaksi adalah:
Jika System.Reflection termasuk dalam blok using:
sumber
Bagaimana dengan ini:
sumber
Saya pikir Anda harus bisa mendapatkannya dari membuat StackTrace . Atau, seperti yang disebutkan @ edg dan @ Lars Mæhlum , MethodBase. GetCurrentMethod ()
sumber
Coba ini...
sumber
Saya hanya melakukan ini dengan kelas statis sederhana:
lalu dalam kode Anda:
sumber
sumber