簡體   English   中英

反射:通用列表的非通用子類中包含的項類型

[英]Reflection: Type of item contained in non-generic subclass of generic list

public class MyList : List<MyClass>

如果我有一個包含MyList實例的object ,如何通過反射獲取MyClass類型? 列表可以為空,所以我不能做像myList[0].GetType()這樣的事情。

ps我不能只停止使用MyList並直接使用通用List(情況有點復雜,並且有“隱藏”泛型參數的原因),所以我無法通過GetGenericArguments()獲取MyClass

var elementType = (
    from iface in myList.GetType().GetInterfaces()
    where iface.IsGenericType
    where iface.GetGenericTypeDefinition() == typeof(IList<>)
    select iface.GetGenericArguments()[0])
        .Single();

我使用IList<T>而不是list。 這更通用。 但是,還有一個實現多個ILis<T>版本的類型的更改(例如IList<string>IList<int> )。

你可以得到基類型,它將是List<MyClass> ; 從中你可以使用GetGenericArguments獲取泛型類型參數。

MyList list = new MyList();
Type baseTypeGenericArgument = list.GetType().BaseType.GetGenericArguments()[0];
string argumentTypeName = baseTypeGenericArgument.GetType().FullName;

你的類是否實現了通用接口? 您可以使用以下代碼:

Type argument = GetGenericArgument(typeof(MyList), typeof(IList<>));
//...
static Type GetGenericArgument(Type type, Type genericTypeDefinition) {
    Type[] interfaces = type.GetInterfaces();
    for(int i = 0; i < interfaces.Length; i++) {
        if(!interfaces[i].IsGenericType) continue;
        if(interfaces[i].GetGenericTypeDefinition() == genericTypeDefinition)
            return interfaces[i].GetGenericArguments()[0];
    }
    return null;
}

沒有接口,您可以嘗試以下方法:

class A { }
class B { }
class G<T> { }
class G1<T> : G<A> { }
class G2 : G1<B> { }
//...
Type argument1 = GetGenericArgument(typeof(G2)); // B
Type argument2 = GetGenericArgument(typeof(G2),1 ); // A
//...
static Type GetGenericArgument(Type type, int level = 0) {
    do {
        if(type.IsGenericType && 0 == level--)
            return type.GetGenericArguments()[0];
        type = type.BaseType;
    }
    while(type != null);
    return null;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM