2011-01-04 8 views
11

Mam ogólny typ następującoJak uzyskać dostęp do właściwości rodzajowe bez znajomości zamkniętą ogólny typ

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

Jeśli mam teraz obiekt (który pochodzi z jakiegoś zewnętrznego źródła), z którego wiem, że jest to rodzaj jest z zamkniętego TestGeneric <>, ale nie znam TypeParameter T. Teraz muszę uzyskać dostęp do danych mojego obiektu. Problem polega na tym, że nie mogę rzucić obiektu, ponieważ nie wiem dokładnie, który zamknięty testGeneric.

używam

// 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; 
} 

, aby upewnić się, mój obiekt jest typu rodzajowego. Kod w pytanie jest następujące:

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[] { }); 
    } 
} 

muszę danych niezależnie od jego typu (dobrze, jeśli mogę prosić o jej rodzaju przy użyciu GetType() byłoby w porządku, ale nie jest to konieczne), ponieważ chcę tylko zrzuć go w xml używając ToString().

Wszelkie sugestie? Thanx.

+0

możliwy duplikat [Właściwości Uzyskiwanie dostępu przez Generic parametrem type] (http://stackoverflow.com/questions/3059420/accessing-properties-through- rodzajowy parametr) –

Odpowiedz

8

Musisz znać zamknięty typ klasy ogólnej, zanim uzyskasz dostęp do jej ogólnych elementów. Zastosowanie TestGeneric<> daje definicję typu otwartego, której nie można wywołać bez podania ogólnych argumentów.

Najprostszym sposobem, aby uzyskać wartość właściwości jest zastanowić się nad typu zamkniętego w użyciu bezpośrednio:

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

Byłeś szybszy;) Thx i tak. –

+0

Mam źródło IsSubclassOfRawGeneric z: http://www.extensionmethod.net/csharp/type/issubclassofrawgeneric – JoanComasFdz

3

Ach, przepraszam za to. To był prosty błąd, rodzajowy wersja dzieła, oczywiście musi odczytać

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

Och, stackies ... dlaczego nie ktoś mi punkt do rodzaju dynamic ?? To doskonały przykład wykorzystanie co sprawia, że ​​kod o wiele bardziej czytelny:

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

Oficjalne dokumenty MSDN na temat użycia https://msdn.microsoft.com/en-us/library/Dd264736.aspx To naprawdę wydaje się właściwą odpowiedzią. Czy ktoś może oznaczyć to jako poprawne? –

Powiązane problemy