Saat masuk C #, bagaimana saya bisa mempelajari nama metode yang disebut metode saat ini? Saya tahu semua tentang System.Reflection.MethodBase.GetCurrentMethod()
, tetapi saya ingin pergi satu langkah di bawah ini di jejak tumpukan. Saya telah mempertimbangkan untuk mengurai jejak stack, tetapi saya berharap untuk menemukan cara yang lebih bersih dan lebih eksplisit, seperti Assembly.GetCallingAssembly()
tetapi untuk metode.
c#
.net
logging
stack-trace
system.diagnostics
flipdoubt
sumber
sumber
StackTrace
,StackFrame
danCallerMemberName
) dan memposting hasilnya sebagai intisari untuk dilihat orang lain di sini: gist.github.com/wilson0x4d/7b30c3913e74adf4ad99b09163a57a1fJawaban:
Coba ini:
satu garis:
Itu dari Get Calling Method menggunakan Reflection [C #] .
sumber
Di C # 5 Anda bisa mendapatkan informasi itu menggunakan info penelepon :
Anda juga bisa mendapatkan
[CallerFilePath]
dan[CallerLineNumber]
.sumber
[CallerTypeName]
dihapus dari framework .Net saat ini (4.6.2) dan Core CLRAnda dapat menggunakan Informasi Penelepon dan parameter opsional:
Tes ini menggambarkan hal ini:
Sementara StackTrace bekerja sangat cepat di atas dan tidak akan menjadi masalah kinerja dalam banyak kasus, Informasi Penelepon masih jauh lebih cepat. Dalam sampel 1000 iterasi, saya mencatatnya 40 kali lebih cepat.
sumber
CachingHelpers.WhoseThere("wrong name!");
==>"wrong name!"
karenaCallerMemberName
ini hanya menggantikan nilai default.this
memasukkan parameter eksplisit apa pun ke dalam metode ekstensi. Juga, Olivier benar, Anda dapat memberikan nilai dan[CallerMemberName]
tidak diterapkan; alih-alih berfungsi sebagai pengganti di mana nilai default biasanya digunakan. Faktanya, jika kita melihat IL kita dapat melihat bahwa metode yang dihasilkan tidak berbeda dari apa yang biasanya dipancarkan untuk[opt]
arg, injeksiCallerMemberName
karena itu merupakan perilaku CLR. Terakhir, dokumen: "Atribut Info Penelepon [...] memengaruhi nilai default yang diteruskan ketika argumen dihilangkan "async
ramah yangStackFrame
tidak akan membantu Anda. Juga tidak mempengaruhi dipanggil dari lambda.Rekap cepat dari 2 pendekatan dengan perbandingan kecepatan menjadi bagian penting.
http://geekswithblogs.net/BlackRabbitCoder/archive/2013/07/25/c.net-little-wonders-getting-caller-information.aspx
Menentukan penelepon pada waktu kompilasi
Menentukan penelepon menggunakan tumpukan
Perbandingan kedua pendekatan tersebut
sumber
Kita dapat memperbaiki kode Mr Assad (jawaban yang diterima saat ini) hanya sedikit dengan membuat instance hanya frame yang sebenarnya kita butuhkan daripada seluruh tumpukan:
Ini mungkin melakukan sedikit lebih baik, meskipun kemungkinan masih harus menggunakan tumpukan penuh untuk membuat bingkai tunggal itu. Juga, itu masih memiliki peringatan yang sama yang ditunjukkan oleh Alex Lyman (pengoptimal / kode asli mungkin merusak hasil). Akhirnya, Anda mungkin ingin memeriksa untuk memastikannya
new StackFrame(1)
atau.GetFrame(1)
tidak kembalinull
, tidak mungkin seperti kemungkinan itu muncul.Lihat pertanyaan terkait ini: Dapatkah Anda menggunakan refleksi untuk menemukan nama metode yang sedang dijalankan?
sumber
new ClassName(…)
sama dengan nol?Secara umum, Anda bisa menggunakan
System.Diagnostics.StackTrace
kelas untuk mendapatkanSystem.Diagnostics.StackFrame
, dan kemudian menggunakanGetMethod()
metode untuk mendapatkanSystem.Reflection.MethodBase
objek. Namun, ada beberapa peringatan untuk pendekatan ini:( CATATAN: Saya hanya memperluas jawaban yang diberikan oleh Firas Assad .)
sumber
Pada. NET 4.5 Anda dapat menggunakan Atribut Informasi Penelepon :
CallerFilePath
- File sumber yang disebut fungsi;CallerLineNumber
- Baris kode yang disebut fungsi;CallerMemberName
- Anggota yang memanggil fungsi.Fasilitas ini juga hadir dalam ".NET Core" dan ".NET Standard".
Referensi
CallerFilePathAttribute
KelasCallerLineNumberAttribute
KelasCallerMemberNameAttribute
Kelassumber
Perhatikan bahwa hal itu tidak akan dapat diandalkan dalam kode rilis, karena optimasi. Selain itu, menjalankan aplikasi dalam mode kotak pasir (berbagi jaringan) tidak akan memungkinkan Anda untuk mengambil bingkai tumpukan sama sekali.
Pertimbangkan pemrograman berorientasi aspek (AOP), seperti PostSharp , yang alih-alih dipanggil dari kode Anda, memodifikasi kode Anda, dan karenanya tahu di mana ia berada setiap saat.
sumber
Jelas ini adalah jawaban yang terlambat, tetapi saya memiliki pilihan yang lebih baik jika Anda dapat menggunakan .NET 4.5 atau lebih:
Ini akan mencetak Tanggal dan Waktu saat ini, diikuti oleh "Namespace.ClassName.MethodName" dan diakhiri dengan ": teks".
Output sampel:
Penggunaan sampel:
sumber
sumber
Mungkin Anda mencari sesuatu seperti ini:
sumber
Kelas yang fantastis ada di sini: http://www.csharp411.com/c-get-calling-method/
sumber
Pendekatan lain yang saya gunakan adalah menambahkan parameter ke metode yang dimaksud. Misalnya, alih-alih
void Foo()
, gunakanvoid Foo(string context)
. Kemudian masukkan beberapa string unik yang menunjukkan konteks panggilan.Jika Anda hanya membutuhkan penelepon / konteks untuk pengembangan, Anda dapat menghapus
param
sebelum pengiriman.sumber
Untuk mendapatkan Nama Metode dan Nama Kelas coba ini:
sumber
akan cukup, saya pikir.
sumber
Lihatlah nama metode Logging di .NET . Waspadalah menggunakannya dalam kode produksi. StackFrame mungkin tidak dapat diandalkan ...
sumber
Kita juga dapat menggunakan lambda untuk menemukan penelepon.
Misalkan Anda memiliki metode yang ditentukan oleh Anda:
dan Anda ingin menemukan itu penelepon.
1 . Ubah tanda tangan metode sehingga kami memiliki parameter tipe Action (Func juga akan berfungsi):
2 . Nama Lambda tidak dihasilkan secara acak. Aturannya tampaknya:> <CallerMethodName> __X di mana CallerMethodName digantikan oleh fungsi sebelumnya dan X adalah indeks.
3 . Ketika kita memanggil MethodA, parameter Action / Func harus dihasilkan oleh metode pemanggil. Contoh:
4 . Di dalam MethodA kita sekarang dapat memanggil fungsi helper yang didefinisikan di atas dan menemukan MethodInfo dari metode pemanggil.
Contoh:
sumber
Informasi tambahan untuk jawaban Firas Assaad.
Saya telah menggunakan
new StackFrame(1).GetMethod().Name;
.net core 2.1 dengan injeksi ketergantungan dan saya mendapatkan metode panggilan sebagai 'Mulai'.Saya mencoba
[System.Runtime.CompilerServices.CallerMemberName] string callerName = ""
dan itu memberi saya metode panggilan yang benarsumber
sumber