2012-12-22 33 views
8

Khi phát xung quanh với sự phản chiếu trong Khuôn khổ .NET 4.5 mới, tôi gặp phải một hành vi lạ mà tôi thấy khá bất ngờ. Không gian tên System.Reflection cung cấp một số phương thức mở rộng mới để khai thác các đối tượng Type. Hai trong số đó là GetRuntimeProperty (tên chuỗi) và GetRuntimeProperties().Phản ánh: hành vi khung không phù hợp với các phương thức GetRuntimeProperty

Bây giờ hãy tưởng tượng rằng bạn có một đối tượng đơn giản với thuộc tính nội bộ.

public class ObjectBase 
{ 
    protected int Id { get; set; } 
    public string Name { get; set; } 
} 

Và bây giờ bạn cố gắng khai thác loại này.

var properties = typeof(ObjectBase).GetRuntimeProperties(); 
// properties.Count = 2 

var idProperty = typeof(ObjectBase).GetRuntimeProperty("Id"); 
var nameProperty = typeof(ObjectBase).GetRuntimeProperty("Name"); 
// idProperty = null 
// nameProperty = System.String Name 

Đúng như dự đoán đối tượng properties giữ hai định nghĩa thuộc tính cho Id và Tên defintions bất động sản và các nameProperty giữ nét Tên tài sản. Những gì không được mong đợi là đối tượng idProperty là null ...

Đến từ .NET Framework, tôi đoán đây là dự định của các kiến ​​trúc sư Microsoft nhưng tôi phải nói nó dường như không giống như điều bạn thực sự mong đợi xảy ra. Tôi tin rằng các phương pháp tương tự như vậy sẽ hoạt động giống nhau nhưng có vẻ như các bộ lọc GetRuntimeProperty trên các thuộc tính công cộng mà GetRuntimeProperties không áp dụng bộ lọc nào.

Có ai có giải thích hợp lý về lý do tại sao Microsoft quyết định rằng những phương pháp tương tự đó nên có các hành vi khác nhau không? Lỗi thiết kế?

Cảm ơn.

+0

Hãy nhớ rằng việc sử dụng tính năng này chỉ bắt buộc trong ứng dụng Cửa hàng. Vì vậy, những gì bạn đang thấy là một sự thỏa hiệp, IInspectable không chính xác là một giao diện phong phú. –

+0

Họ hoàn toàn buggered lên các API phản ánh mới. Đó là một mớ hỗn độn theo nhiều cách mà tôi thậm chí không biết bắt đầu từ đâu. –

Trả lời

3

Nội bộ GetRuntimeProperty gọi Type.GetProperty(name) tìm kiếm thuộc tính công khai với tên được chỉ định. Bất động sản Id được bảo vệ, do đó nó không thể được tìm thấy.

public static PropertyInfo GetRuntimeProperty(this Type type, string name) 
{ 
    CheckAndThrow(type); 
    return type.GetProperty(name); 
} 

Mặt khác GetRuntimeProperties lợi nhuận cả tài sản công cộng và ngoài công lập

public static IEnumerable<PropertyInfo> GetRuntimeProperties(this Type type) 
{ 
    CheckAndThrow(type); 
    return type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | 
           BindingFlags.Static | BindingFlags.Instance); 
} 

Explanation:GetRuntimeProperties mục đích là trở về IEnumerable<PropertyInfo> bộ sưu tập của tất cả các tài sản, để lại cho bạn lọc bộ sưu tập mà qua LINQ. Bạn có thể chọn loại công khai, không công khai hoặc bất kỳ loại thuộc tính nào khác. Với một thuộc tính duy nhất được trả về bởi GetRuntimeProperty, bạn không cần sự linh hoạt đó, do đó nó bị hạn chế cho việc sử dụng phổ biến nhất.

+4

Câu hỏi đặt ra là: nhút nhát được thiết kế như thế này. Không có ý nghĩa nhiều. Có vẻ như một lỗi thiết kế cho tôi. – Steven

+0

Như @Steven đã nói, tôi thực sự hiểu rằng nó được mã hóa như thế này nội bộ nhưng những gì tôi không hiểu là lý do tại sao những phương pháp này hoạt động khác nhau. Tôi đã cập nhật câu hỏi của mình để rõ ràng hơn. Cảm ơn. – Ucodia

+1

@Ucodia, Steven - Tôi đã thêm giải thích và liên kết. Như bạn có thể thấy, đó là quyết định thiết kế. Nếu bạn cần thuộc tính không công khai, hãy sử dụng LINQ để lấy nó 'typeof (ObjectBase) .GetRuntimeProperties(). Single (p => p.Name ==" Id ")' –

Các vấn đề liên quan