2012-06-22 16 views
9

Hãy xem xét các lớp sau đây:Làm thế nào tôi có thể sử dụng Reflection để có được giá trị của một tài sản tĩnh của một loại mà không có một trường hợp cụ thể

public class AClass : ISomeInterface 
{ 
    public static int AProperty 
    { 
    get { return 100; } 
    } 
} 

sau đó tôi có một lớp học như sau:

public class AnotherClass<T> 
    where T : ISomeInterface 
{ 

} 

mà tôi dụ qua:

AnotherClass<AClass> genericClass = new AnotherClass<AClass>(); 

Làm thế nào tôi có thể nhận được giá trị tĩnh của AClass.AProperty từ bên trong genericClass của tôi mà không có một ví dụ cụ thể của AClass?

Trả lời

10

Something như

typeof(AClass).GetProperty("AProperty").GetValue(null, null) 

sẽ làm. Đừng quên truyền tới int.

Liên kết tài liệu: http://msdn.microsoft.com/en-us/library/b05d59ty.aspx (chúng cũng có ví dụ với thuộc tính tĩnh). Nhưng nếu bạn biết chính xác AClass, bạn có thể sử dụng chỉ AClass.AProperty.

Nếu bạn đang ở trong AnotherClass<T> cho T = AClass, bạn có thể tham khảo nó như T:

typeof(T).GetProperty("AProperty").GetValue(null, null) 

Điều này sẽ có tác dụng nếu bạn biết chắc chắn rằng T của bạn có sở hữu AProperty tĩnh. Nếu không đảm bảo rằng tài sản đó tồn tại trên bất kỳ T nào, bạn cần phải kiểm tra giá trị trả lại/ngoại lệ trên đường đi.

Nếu chỉ AClass là thú vị cho bạn, bạn có thể sử dụng một cái gì đó giống như

if (typeof(T) == typeof(AClass)) 
    n = AClass.AProperty; 
else 
    ??? 
+0

Tuyệt vời. Vấn đề duy nhất tôi đã phát hiện ra là tôi không thể định nghĩa thuộc tính tĩnh trong giao diện mà nó cần phải làm. Tôi đoán tôi có thể thêm một tài sản không tĩnh và một tài sản tĩnh trả lại cùng một giá trị, một cho các ví dụ để sử dụng và một để được tham chiếu trên các loại? Hay có cách nào khác làm tròn nó? –

+0

Ngoài ra tôi có thể nhận được tài sản không tĩnh bằng cách sử dụng T() mới. AProperty, nhưng điều này có vẻ như nó sẽ là thực hành xấu. Bạn nghĩ sao? –

+0

@Stewart: Vâng, việc xây dựng một 'T' mới có thể tốn kém. Thật đáng tiếc là các giao diện không thể bao gồm những thứ tĩnh. – Vlad

1

đầu tiên nhận được các loại chung của AnotherClass dụ của bạn.

Sau đó nhận thuộc tính tĩnh.

Sau đó nhận giá trị tĩnh của thuộc tính.

// I made this sealed to ensure that `this.GetType()` will always be a generic 
// type of `AnotherClass<>`. 
public sealed class AnotherClass<T> 
{ 
    public AnotherClass(){ 
     var aPropertyValue = ((PropertyInfo) 
       this.GetType() 
        .GetGenericArguments()[0] 
        .GetMember("AProperty")[0]) 
      .GetValue(null, null); 
    } 
} 

Nhận, tất nhiên, nó không thể đảm bảo rằng "AProperty" sẽ tồn tại, bởi vì giao diện không làm việc trên chữ ký tĩnh, tôi loại bỏ ISomeInterface như là không liên quan đến các giải pháp.

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