反射:通用列表的非通用子类中包含的项目类型

发布于 2024-12-29 06:40:20 字数 366 浏览 2 评论 0原文

public class MyList : List<MyClass>

如果我有一个包含 MyList 实例的 object ,如何通过反射获取类型 MyClass ?该列表可以为空,因此我无法执行诸如 myList[0].GetType() 之类的操作。

ps 我不能停止使用 MyList 并直接使用泛型 List (情况稍微复杂一点,并且有“隐藏”泛型参数的原因),所以我不能通过 GetGenericArguments() 获取 MyClass

public class MyList : List<MyClass>

How can I get the type MyClass through reflection if I have an object that contains an instance of MyList? The list can be empty, so I can't do something like myList[0].GetType().

p.s. I can't just stop using MyList and directly use the generic List instead (the situation is a bit more complicated, and there are reasons for "hiding" the generic argument), so I can't pick up MyClass through GetGenericArguments().

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

帅的被狗咬 2025-01-05 06:40:20
var elementType = (
    from iface in myList.GetType().GetInterfaces()
    where iface.IsGenericType
    where iface.GetGenericTypeDefinition() == typeof(IList<>)
    select iface.GetGenericArguments()[0])
        .Single();

我使用 IList 而不是列表。这个比较通用。然而,实现多个 ILis 版本(例如 IListIList)的类型也发生了变化。 )。

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

I use IList<T> instead of list. This is more generic. However, there is also the change of a type implementing multiple ILis<T> versions (such as IList<string> and IList<int>).

活泼老夫 2025-01-05 06:40:20

您可以获得基本类型,即List;从中您可以使用 GetGenericArguments 获取通用类型参数。

You can get the base type, which will be List<MyClass>; from it you can get the generic type argument with GetGenericArguments.

盛装女皇 2025-01-05 06:40:20
MyList list = new MyList();
Type baseTypeGenericArgument = list.GetType().BaseType.GetGenericArguments()[0];
string argumentTypeName = baseTypeGenericArgument.GetType().FullName;
MyList list = new MyList();
Type baseTypeGenericArgument = list.GetType().BaseType.GetGenericArguments()[0];
string argumentTypeName = baseTypeGenericArgument.GetType().FullName;
野心澎湃 2025-01-05 06:40:20

你的类实现了通用接口吗?您可以使用以下代码:

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

Is your class implements generic interfaces? you can use the following code:

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

Without interfaces you can try the following:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文