2011-01-04 38 views
11

Tôi có một loại chung như sauLàm thế nào để truy cập vào tài sản chung mà không biết loại generic kín

public class TestGeneric<T> 
{ 
    public T Data { get; set; } 
    public TestGeneric(T data) 
    { 
     this.Data = data; 
    } 
} 

Nếu tôi có bây giờ là một đối tượng (trong đó xuất phát từ một số nguồn bên ngoài) mà từ đó tôi biết rằng đó là loại là của một số TestGeneric <> đóng, nhưng tôi không biết TypeParameter T. Bây giờ tôi cần truy cập Dữ liệu của đối tượng của tôi. Vấn đề là tôi không thể cast đối tượng, vì tôi không biết chính xác cái nào đóng TestGeneric.

tôi sử dụng

// thx to http://stackoverflow.com/questions/457676/c-reflection-check-if-a-class-is-derived-from-a-generic-class 
private static bool IsSubclassOfRawGeneric(Type rawGeneric, Type subclass) 
{ 
    while (subclass != typeof(object)) 
    { 
     var cur = subclass.IsGenericType ? subclass.GetGenericTypeDefinition() : subclass; 
     if (rawGeneric == cur) 
     { 
      return true; 
     } 
     subclass = subclass.BaseType; 
    } 
    return false; 
} 

chắc chắn, đối tượng của tôi là loại generic. Các mã trong câu hỏi là như sau:

public static void Main() 
{ 
    object myObject = new TestGeneric<string>("test"); // or from another source 
    if (IsSubclassOfRawGeneric(typeof(TestGeneric<>), myObject.GetType())) 
    { 
     // the following gives an InvalidCastException 
     // var data = ((TestGeneric<object>)myObject).Data; 

     // if i try to access the property with reflection 
     // i get an InvalidOperationException 
     var dataProperty = typeof(TestGeneric<>).GetProperty("Data"); 
     object data = dataProperty.GetValue(myObject, new object[] { }); 
    } 
} 

tôi cần những dữ liệu bất kể loại của nó (tốt, nếu tôi có thể yêu cầu loại này sử dụng GetType() sẽ là tốt, nhưng không cần thiết) kể từ khi tôi chỉ muốn đổ nó vào xml bằng ToString().

Mọi đề xuất? Thanx.

+0

thể trùng lặp của [Truy cập vào các thuộc tính thông qua tham số kiểu Generic] (http://stackoverflow.com/questions/3059420/accessing-properties-through- generic-type-parameter) –

Trả lời

8

Bạn cần phải biết loại đóng của một lớp chung trước khi bạn có thể truy cập các thành viên chung của nó. Việc sử dụng TestGeneric<> cung cấp cho bạn định nghĩa kiểu mở, không thể được gọi ra mà không chỉ định các đối số chung.

Cách đơn giản nhất để bạn có thể nhận được giá trị của tài sản là để phản ánh vào loại khép kín trong việc sử dụng trực tiếp:

public static void Main() 
{ 
    object myObject = new TestGeneric<string>("test"); // or from another source 

    var type = myObject.GetType(); 

    if (IsSubclassOfRawGeneric(typeof(TestGeneric<>), type)) 
    { 
     var dataProperty = type.GetProperty("Data"); 
     object data = dataProperty.GetValue(myObject, new object[] { }); 
    } 
} 
+0

Bạn đã nhanh hơn;) Thx anyway. –

+0

Tôi đã nhận nguồn IsSubclassOfRawGeneric từ: http://www.extensionmethod.net/csharp/type/issubclassofrawgeneric – JoanComasFdz

3

Ahh, xin lỗi vì điều đó. Đó là một sai lầm đơn giản, các công trình phiên bản generic, tất nhiên nó phải đọc

var dataProperty = myObject.GetType().GetProperty("Data"); 
object data = dataProperty.GetValue(myObject, new object[] { }); 
24

Oh, stackies ... tại sao không có ai chỉ cho tôi loại dynamic ?? Đó là ví dụ sử dụng hoàn hảo mà làm cho mã A LOT dễ đọc hơn:

dynamic dynObject = myObject; 
object data = dynObject.Data; 
+1

Tài liệu MSDN chính thức về cách sử dụng https://msdn.microsoft.com/en-us/library/Dd264736.aspx Điều này thực sự cảm thấy giống như câu trả lời thích hợp. Ai đó có thể đánh dấu nó đúng không? –

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