Tôi biết bạn có thể làmLàm thế nào để có được tên của phương pháp hiện tại từ mã
this.GetType().FullName
Để có được
My.Current.Class
Nhưng những gì tôi có thể gọi để có được
My.Current.Class.CurrentMethod
Tôi biết bạn có thể làmLàm thế nào để có được tên của phương pháp hiện tại từ mã
this.GetType().FullName
Để có được
My.Current.Class
Nhưng những gì tôi có thể gọi để có được
My.Current.Class.CurrentMethod
StackTrace st = new StackTrace();
StackFrame sf = st.GetFrame (0);
MethodBase currentMethodName = sf.GetMethod();
Hoặc, nếu bạn muốn có một phương pháp helper:
[MethodImpl(MethodImplOptions.NoInlining)]
public string GetCurrentMethod()
{
StackTrace st = new StackTrace();
StackFrame sf = st.GetFrame (1);
return sf.GetMethod().Name;
}
cập nhật với các khoản tín dụng để @stusmith.
Ghi nhớ JIT là miễn phí đối với các phương thức nội tuyến, điều này có thể làm giảm tính năng này. Để buộc một phương thức không được gạch chân, hãy thêm thuộc tính [MethodImpl (MethodImplOptions.NoInlining)]. – stusmith
@stusmith: Cảm ơn! Sẽ nhớ nó! –
@stusmith Cảm ơn –
Kiểm tra này ra: http://www.codeproject.com/KB/dotnet/MethodName.aspx
void MyMethod() { chuỗi hiện tạiMethodName = nameof (MyMethod); // etc ... } –
Gọi System.Reflection.MethodBase.GetCurrentMethod().Name
từ trong phương thức.
Bạn cũng có thể sử dụng MethodBase.GetCurrentMethod()
sẽ chặn trình biên dịch JIT khỏi nội tuyến mà phương thức được sử dụng.
Cập nhật:
Phương pháp này có chứa một thống kê ðặc biệt StackCrawlMark
rằng từ hiểu biết của tôi sẽ chỉ định để trình biên dịch JIT rằng phương pháp hiện nay không nên được inlined.
Đây là cách giải thích của tôi về nhận xét liên quan đến hiện diện điều tra đó trong SSCLI. Nhận xét sau:
// declaring a local var of this enum type and passing it by ref into a function
// that needs to do a stack crawl will both prevent inlining of the calle and
// pass an ESP point to stack crawl to
//
// Declaring these in EH clauses is illegal;
// they must declared in the main method body
Bạn có một tham chiếu giải thích cách 'GetCurrentMethod' ức chế JIT từ nội tuyến phương thức gọi không? – LukeH
@Luke, tôi cập nhật câu trả lời của tôi với lý do tại sao tôi tin rằng phương pháp này sẽ ức chế nội tuyến. –
Cảm ơn, điều đó rất thú vị, mặc dù nó không hoàn toàn rõ ràng với tôi cho dù nó ngăn cản nội tuyến của phương thức khai báo 'StackCrawlMark' cục bộ hay người gọi phương thức đó. – LukeH
Phản ánh có một sở trường để ẩn rừng cho cây. Bạn không bao giờ gặp sự cố khi nhận tên phương thức hiện tại một cách chính xác và nhanh chóng:
void MyMethod() {
string currentMethodName = "MyMethod";
//etc...
}
Mặc dù công cụ tái cấu trúc có thể sẽ không tự động sửa chữa.
Nếu bạn hoàn toàn không quan tâm đến chi phí (đáng kể) của việc sử dụng Reflection sau đó phương pháp helper này nên có ích:
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Reflection;
//...
[MethodImpl(MethodImplOptions.NoInlining)]
public static string GetMyMethodName() {
var st = new StackTrace(new StackFrame(1));
return st.GetFrame(0).GetMethod().Name;
}
Cập nhật: C# phiên bản 5 và .NET 4.5 có vàng giải pháp cho nhu cầu chung này, bạn có thể sử dụng [CallerMemberName] attribute để trình biên dịch tự động tạo tên của phương thức gọi trong đối số chuỗi. Các thuộc tính hữu ích khác là [CallerFilePath] để trình biên dịch tạo đường dẫn tệp mã nguồn và [CallerLineNumber] để lấy số dòng trong tệp mã nguồn cho câu lệnh đã thực hiện cuộc gọi.
Update2: cú pháp tôi đề nghị ở đầu câu trả lời bây giờ có thể được thực hiện để làm việc trong C# phiên bản 6 mà không có một công cụ refactoring ưa thích:
string currentMethodName = nameof(MyMethod);
Tôi đã làm điều này trước đây. Có thể là một sod để duy trì nếu bạn làm điều này ứng dụng rộng, nhưng nếu không: nhịp đơn giản thông minh bất cứ ngày nào! –
Từ đúng, nhanh hơn khoảng 10.000 lần, đưa ra hoặc lấy hệ số 10. –
+1 cho đầu đề [CallerMemberNameAttribute] .NET 4.5. Cảm ơn. –
Điều này không làm việc?
System.Reflection.MethodBase.GetCurrentMethod()
Trả về đối tượng MethodBase đại diện cho phương pháp hiện đang thực thi.
Namespace: System.Reflection
hội: mscorlib (trong mscorlib.dll)
http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getcurrentmethod.aspx
Vâng System.Reflection.MethodBase.GetCurrentMethod().Name
không phải là một lựa chọn rất tốt vì nó sẽ chỉ hiển thị tên phương pháp không có thông tin bổ sung.
Thích cho string MyMethod(string str)
thuộc tính trên sẽ chỉ trả lại MyMethod
không đủ.
Nó là tốt hơn để sử dụng System.Reflection.MethodBase.GetCurrentMethod().ToString()
đó sẽ trả lại toàn bộ chữ ký phương pháp ...
Tôi nhận được MoveNext thay vì tên phương thức của mình. –
Tôi nghĩ rằng cách tốt nhất để có được tên đầy đủ là:
this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;
hoặc thử này
string method = string.Format("{0}.{1}", MethodBase.GetCurrentMethod().DeclaringType.FullName, MethodBase.GetCurrentMethod().Name);
+1 vì việc sử dụng sự phản chiếu nhanh hơn nhiều so với việc sử dụng StackTrace. –
Điều này không hoạt động đối với các phương thức 'async'. Tôi gọi 'System.Reflection.MethodBase.GetCurrentMethod(). Name' trên dòng đầu tiên của một phương thức và tôi nhận' MoveNext'. – Gusdor
Có thể tạo hàm sẽ trả về tên/tên hàm của người gọi không? Giải pháp của bạn là tuyệt vời, nhưng một chút dài để được gọi là mỗi lần.Nó sẽ là lý tưởng nếu điều này có thể được trên một số lớp khác và chức năng công cộng hoặc có lẽ tài sản công cộng có thể được gọi. Lý tưởng nhất là ở một số lớp tĩnh. – FrenkyB
'this.ToString()' cung cấp cho bạn tên lớp hiện tại chỉ khi bạn không thực hiện bất kỳ điều gì đặc biệt trong chuỗi 'công khai ghi đè lên ToString()' của riêng bạn. 'GetType(). FullName' không cung cấp cho bạn tên đầy đủ. –
@Pasi cảm ơn, sẽ thay đổi việc triển khai của tôi –
Trong .Net 4.5, bạn có thể sử dụng CallerMemberNameAttribute để lấy tên của người gọi. Xem https://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.callermembernameattribute(v=vs.110).aspx ... Sau đó bạn có thể quấn phần thân của hàm của bạn vào một hàm ẩn danh như trong ([CallerMemberName] string functionName = "") => {}. Các vấn đề với việc sử dụng phương pháp phản xạ như trong câu trả lời được chấp nhận là (1) chức năng có thể được gạch chân, và/hoặc (2) tên hàm có thể bị xáo trộn nếu nó không công khai và mã bị che khuất. – GreatAndPowerfulOz