2009-04-29 26 views
15

tôi có thể hỏi này không chính xác, nhưng có thể/làm thế nào bạn có thể tìm thấy các lĩnh vực trên một lớp bên trong nó ... ví dụ ...C# Reflection: Finding Thuộc tính trên Dòng Member

public class HtmlPart { 
    public void Render() { 
    //this.GetType().GetCustomAttributes(typeof(OptionalAttribute), false); 
    } 
} 

public class HtmlForm { 
    private HtmlPart _FirstPart = new HtmlPart();  
    [Optional] //<-- how do I find that? 
    private HtmlPart _SecondPart = new HtmlPart(); 
} 

Hoặc có lẽ tôi chỉ làm điều này không chính xác ... Làm thế nào tôi có thể gọi một phương pháp và sau đó kiểm tra các thuộc tính áp dụng cho chính nó?

Ngoài ra, vì lợi ích của câu hỏi - Tôi chỉ tò mò nếu có thể tìm thông tin thuộc tính mà không biết/truy cập lớp cha!

Trả lời

12

Nếu tôi hiểu câu hỏi của bạn một cách chính xác, tôi nghĩ rằng những gì bạn đang cố gắng làm là không thể ...

Trong phương pháp Render, bạn muốn nhận được một thuộc tính có thể áp dụng cho các đối tượng. Thuộc tính thuộc về trường _SecondPart phù thủy thuộc về lớp HtmlForm.

Cho rằng để làm việc bạn sẽ phải vượt qua các đối tượng gọi điện thoại đến các phương pháp Render:

public class HtmlPart { 
     public void Render(object obj) { 
      FieldInfo[] infos = obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); 

      foreach (var fi in infos) 
      { 
       if (fi.GetValue(obj) == this && fi.IsDefined(typeof(OptionalAttribute), true)) 
        Console.WriteLine("Optional is Defined"); 
      } 
     } 
    } 
+0

Cảm ơn - Nó có vẻ là 'có thể', nhưng sau đó một lần nữa tôi figured có chỉ là đủ mất tích mà nó không thể làm việc. – Hugoware

+2

Không, phương pháp Render hoàn toàn có thể truy cập tốt typeof (HtmlForm) thay vì obj.GetType(), sau đó bạn không cần obj nữa. Tất nhiên, nếu chính HtmlForm là riêng, thì bạn có thể cần phải tìm nó thông qua Assembly.GetExecutingAssembly() GetTypes(). Ở đâu (t =>! T.IsGeneric &&! T.IsNested && t.FullName == "MyNamespace. HtmlForm ") hoặc một cái gì đó như thế. – Timwi

5

Bạn có thể tìm thấy các lĩnh vực trong một lớp học sử dụng Type.GetFields, và bạn có thể tìm thấy thuộc tính áp dụng cho một lĩnh vực sử dụng MemberInfo.GetCustomAttributes hay IsDefined - nhưng nếu bạn cần phải tìm tất cả các lĩnh vực của một loại đặc biệt, bạn sẽ phải :

  • lặp qua tất cả các hội đồng bạn muốn tìm kiếm
  • lặp qua tất cả các loại trong mỗi lắp ráp
  • lặp trên tất cả các lĩnh vực trong từng loại
  • Kiểm tra sự hiện diện/vắng mặt của thuộc tính cho từng trường

Bây giờ, nếu bạn thực sự cố gắng tìm ra "là một thuộc tính cụ thể được áp dụng cho trường có giá trị là tham chiếu đến đối tượng 'này' thì đó là thậm chí còn khó hơn - bởi vì bạn phải biết tất cả về mọi đối tượng trong hệ thống. Bạn cũng nên nhớ rằng có thể có hai trường đều có cùng giá trị, nghĩa là tham chiếu cùng một đối tượng. Đối tượng sẽ được tính là "tùy chọn" trong trường hợp đó hay không?

Về cơ bản, nếu đối tượng cần có thuộc tính (ví dụ: tùy chọn hay không) thì đó phải là thuộc tính của đối tượng, chứ không phải trường chứa thuộc tính.

Có thể tôi hiểu sai những gì bạn đang cố gắng làm, nhưng tôi nghi ngờ hoặc là không khả thi hoặc ít nhất cũng không phải là ý tưởng hay. Bạn có thể giải thích bức tranh lớn hơn ở đây không? Bạn đang thực sự cố gắng đạt được gì với thuộc tính này?

+0

Cảm ơn đã phản ứng - Ngay bây giờ nó nhiều hơn một thí nghiệm hơn bất cứ điều gì khác. Tôi tự hỏi liệu điều đó có thể xảy ra hay không vì đây là một cách kỳ quặc để thử và tiếp cận thông tin đó. – Hugoware

10

Dưới đây là một ví dụ về cho một đối tượng duy nhất làm thế nào để tìm thấy nếu bất kỳ lĩnh vực công hay tư trên đối tượng đó có một tài sản cụ thể:

var type = typeof(MyObject); 
foreach (var field in type.GetFields(BindingFlags.Public | 
      BindingFlags.NonPublic | BindingFlags.Instance)) 
{ 
    if (field.IsDefined(typeof(ObsoleteAttribute), true)) 
    { 
     Console.WriteLine(field.Name); 
    } 

} 

Đối với phần thứ hai của câu hỏi của bạn, bạn có thể kiểm tra nếu một thuộc tính là defiend vào phương pháp hiện tại sử dụng:

MethodInfo.GetCurrentMethod().IsDefined(typeof(ObsoleteAttribute)); 

Sửa

Để trả lời chỉnh sửa của bạn có nó tôi có thể mà không biết loại thực tế. Hàm sau lấy một tham số kiểu và trả về tất cả các trường có thuộc tính đã cho. Ai đó ở đâu đó sẽ biết Loại bạn muốn tìm kiếm hoặc sẽ có một phiên bản loại bạn muốn tìm kiếm.

Nếu không có điều đó, bạn cần phải làm như Jon Skeet nói đó là liệt kê tất cả các đối tượng trong một hội đồng.

public List<FieldInfo> FindFields(Type type, Type attribute) 
    { 
     var fields = new List<FieldInfo>(); 
     foreach (var field in type.GetFields(BindingFlags.Public | 
          BindingFlags.NonPublic | 
          BindingFlags.Instance)) 
     { 
      if (field.IsDefined(attribute, true)) 
      { 
       fields.Add(field); 
      } 

     } 
     return fields; 
    } 
Các vấn đề liên quan