2010-02-05 40 views
18

Vì vậy, trong trường hợp của tôi, tôi đang khám phá cấu trúc của một lớp bằng cách sử dụng sự phản chiếu. Tôi cần để có thể tìm hiểu xem một tài sản là một tài sản tự động thực hiện bởi các đối tượng PropertyInfo. Tôi cho rằng API phản chiếu không trưng ra chức năng như vậy bởi vì các thuộc tính tự động phụ thuộc C#, nhưng có cách giải quyết nào để lấy thông tin này không?Cách tìm hiểu xem thuộc tính có thuộc tính được tự động triển khai có phản ánh không?

Trả lời

16

Bạn có thể kiểm tra xem phương thức get hoặc set có được đánh dấu bằng thuộc tính CompilerGenerated hay không. Sau đó, bạn có thể kết hợp điều đó với tìm kiếm trường riêng tư được đánh dấu bằng thuộc tính CompilerGenerated có chứa tên thuộc tính và chuỗi "BackingField".

lẽ:

public static bool MightBeCouldBeMaybeAutoGeneratedInstanceProperty(
    this PropertyInfo info 
) { 
    bool mightBe = info.GetGetMethod() 
         .GetCustomAttributes(
          typeof(CompilerGeneratedAttribute), 
          true 
         ) 
         .Any(); 
    if (!mightBe) { 
     return false; 
    } 


    bool maybe = info.DeclaringType 
        .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
        .Where(f => f.Name.Contains(info.Name)) 
        .Where(f => f.Name.Contains("BackingField")) 
        .Where(
         f => f.GetCustomAttributes(
          typeof(CompilerGeneratedAttribute), 
          true 
         ).Any() 
        ) 
        .Any(); 

     return maybe; 
    } 

Nó không đánh lừa bằng chứng, khá giòn và có lẽ không cầm tay, nói, Mono.

+0

Thanks a lot Jason, Reflector nói với tôi như vậy trong khi chờ đợi :) nên đã nghĩ về nó trước đó. – Zoki

+1

@ 3o4eTo: Chỉ cần được cảnh báo rằng điều này không đánh lừa bằng chứng, giòn và có thể không di chuyển đến Mono. – jason

+0

Cũng chăm sóc ngoại lệ khi không có người khởi hành trên tài sản. – nawfal

7

này nên làm:

public static bool IsAutoProperty(this PropertyInfo prop) 
{ 
    return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
          .Any(f => f.Name.Contains("<" + prop.Name + ">")); 
} 

Lý do được rằng để tự động tính các Name tài sản của sự ủng hộ FieldInfo sẽ trông như thế:

<PropertName>k__BackingField 

Kể từ khi nhân vật <> sẽ không xuất hiện cho các trường thông thường, một trường có loại điểm đặt tên đó vào trường sao lưu của thuộc tính tự động. Như Jason nói, nó vẫn giòn.

Hoặc để làm cho nó một chút nhanh hơn,

public static bool IsAutoProperty(this PropertyInfo prop) 
{ 
    if (!prop.CanWrite || !prop.CanRead) 
     return false; 

    return prop.DeclaringType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
          .Any(f => f.Name.Contains("<" + prop.Name + ">")); 
} 
Các vấn đề liên quan