2010-06-03 27 views
30

Tôi có một lớp học mà trông giống như sau:Sử dụng System.Reflection để Nhận một của Phương Tên đầy đủ

public class MyClass 
{ 

... 

    protected void MyMethod() 
    { 
    ... 
    string myName = System.Reflection.MethodBase.GetCurrentMethod.Name; 
    ... 
    } 

... 

} 

Giá trị của myName là "MyMethod".

Có cách nào để tôi có thể sử dụng Phản ánh để nhận giá trị "MyClass.MyMethod" cho số myName thay thế không?

+1

Correction: nó phải được System.Reflection.MethodBase.GetCurrentMethod() Tên – aads

Trả lời

50

Bạn có thể nhìn vào ReflectedType của MethodBase bạn nhận được từ GetCurrentMethod, tức là,

MethodBase method = System.Reflection.MethodBase.GetCurrentMethod(); 
string methodName = method.Name; 
string className = method.ReflectedType.Name; 

string fullMethodName = className + "." + methodName; 
+0

Chính xác những gì tôi đang tìm kiếm.. Cảm ơn! –

+0

Chỉ cần lưu ý rằng 'ReflectedType' không tính đến đa hình thời gian chạy như dự kiến ​​có thể .. – user2864740

4

Mở rộng Ruben, bạn có thể có được tên đầy đủ như thế này:

var info = System.Reflection.MethodBase.GetCurrentMethod(); 
var result = string.Format(
       "{0}.{1}.{2}()", 
       info.ReflectedType.Namespace, 
       info.ReflectedType.Name, 
       info.Name); 

Bạn có thể thêm nó với một phương thức tĩnh nhận một tham số MethodBase và tạo chuỗi.

4

Bạn có thể lấy tên đầy đủ như thế này:

var fullMethodName = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.FullName; 
14

Và để có được tên phương pháp đầy đủ với các thông số:

var method = System.Reflection.MethodBase.GetCurrentMethod(); 
var fullName = string.Format("{0}.{1}({2})", method.ReflectedType.FullName, method.Name, string.Join(",", method.GetParameters().Select(o => string.Format("{0} {1}", o.ParameterType, o.Name)).ToArray())); 
+0

+1 Chắc chắn là giải pháp hữu ích nhất.Bao gồm FullName giúp xác định lớp khi cơ sở mã của bạn đã lặp lại tên lớp trong các không gian tên khác nhau. Và bao gồm các tham số giúp phân biệt giữa các phương thức quá tải. –

2

Cảm ơn bài viết ở trên, họ đã giúp tôi để tạo ra một mạnh mẽ loại hệ thống ràng buộc cho MVC 4 HTMLHelpers như sau.

public static MvcHtmlString StrongTypeBinder(this HtmlHelper htmlhelper, Expression<Func<object, string>> SomeLambda) 
    { 
     var body = SomeLambda.Body; 
     var propertyName = ((PropertyInfo)((MemberExpression)body).Member).Name; 
     HtmlString = @" 
      <input type='text' name='@Id' id='@Id'/> 
      "; 
     HtmlString = HtmlString.Replace("@Id", propertyName); 
     var finalstring = new MvcHtmlString(HtmlString); 
     return finalstring; 

    } 

Để sử dụng mã trên trong bất kỳ CSHTML Xem:

@Html.StrongTypeBinder(p=>Model.SelectedDate) 

này cho phép tôi để ràng buộc bất cứ tài sản trong một ViewModel cho bất kỳ loại phần tử HTML tôi muốn. Trong ví dụ trên, tôi ràng buộc trường tên cho dữ liệu đã chọn được đăng lại sau khi người dùng chọn lựa. Chế độ xem sau khi bài đăng tự động hiển thị giá trị đã chọn.

2

Trong C# 6 bạn có thể sử dụng nameof:

string myName = nameof(MyMethod); 
+1

Có, nhưng chỉ trả lại tên, chứ không phải tên đầy đủ. Trong ví dụ được đưa ra, nó trả về chuỗi '" MyMethod "', không phải '' MyClass.MyMethod "'. – Matt

5

Tôi nghĩ rằng những ngày này, cách tốt nhất để làm điều này:

string fullMethodName = $"{typeof(MyClass).FullName}.{nameof(MyMethod)}"; 
+1

Đã tìm kiếm điều này để tôi có thể đăng nhập các tên đủ điều kiện và đây là phương pháp tôi đã sử dụng. Chỉ vì nó nhỏ, đơn giản và làm những gì tôi cần. – onesixtyfourth

0

Bạn sẽ có vấn đề khi chạy bên trong các phương pháp async. Dưới đây là làm thế nào để khắc phục điều đó:

Nếu bạn cần phải hội đủ điều kiện đầy đủ tên lớp, bạn sẽ phải sử dụng DeclaringType.FullName thay vì DeclaringType.Name

Mã này sẽ không hoạt động độc đáo cho các phương pháp ẩn danh hoặc lambda.

static string GetMethodContextName() { 
    var name = new StackTrace().GetFrame(1).GetMethod().GetMethodContextName(); 
} 

static string GetMethodContextName(this MethodBase method) { 
    if (method.DeclaringType.GetInterfaces().Any(i => i == typeof(IAsyncStateMachine))) { 
     var generatedType = method.DeclaringType; 
     var originalType = generatedType.DeclaringType; 
     var foundMethod = originalType.GetMethods(Instance | Static | Public | NonPublic | DeclaredOnly) 
      .Single(m => m.GetCustomAttribute<AsyncStateMachineAttribute>()?.StateMachineType == generatedType); 
     return foundMethod.DeclaringType.Name + "." + foundMethod.Name; 
    } else { 
     return method.DeclaringType.Name + "." + method.Name; 
    } 
} 

Dưới đây là một cách sử dụng ví dụ:

class Program { 
    static void Main(string[] args) { 
     // outputs Program.Main 
     Console.WriteLine(GetMethodContextName()); 
    } 
} 
Các vấn đề liên quan