C# 反射:泛型列表的非泛型子类中包含的项的类型 公共类MyList:列表
如果我有一个包含C# 反射:泛型列表的非泛型子类中包含的项的类型 公共类MyList:列表,c#,reflection,C#,Reflection,如果我有一个包含MyList实例的对象,如何通过反射获取类型MyClass?列表可以为空,因此无法执行类似于myList[0].GetType()的操作 p、 我不能停止使用MyList而直接使用泛型列表(情况有点复杂,有理由“隐藏”泛型参数),因此我无法通过GetGenericArguments()获取基本类型,即List;从中可以获得泛型类型参数。var elementType=( 从myList.GetType().GetInterfaces()中的iface 其中iface.IsGene
MyList
实例的对象,如何通过反射获取类型MyClass
?列表可以为空,因此无法执行类似于myList[0].GetType()的操作
p、 我不能停止使用MyList
而直接使用泛型列表(情况有点复杂,有理由“隐藏”泛型参数),因此我无法通过GetGenericArguments()
获取基本类型,即List
;从中可以获得泛型类型参数。var elementType=(
从myList.GetType().GetInterfaces()中的iface
其中iface.IsGenericType
其中iface.GetGenericTypeDefinition()==typeof(IList)
选择iface.GetGenericArguments()[0])
.Single();
我使用IList而不是list。这是更一般的。但是,实现多个ILS
版本(例如IList
和IList
)的类型也发生了变化。您的类是否实现了通用接口?您可以使用以下代码:
var elementType = (
from iface in myList.GetType().GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() == typeof(IList<>)
select iface.GetGenericArguments()[0])
.Single();
Type参数=getgenericalargument(typeof(MyList),typeof(IList));
//...
静态类型GetGenericArgument(类型类型,类型genericTypeDefinition){
Type[]interfaces=Type.GetInterfaces();
for(int i=0;i
如果没有接口,您可以尝试以下操作:
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{}
B类{}
类G{}
类G1:G{}
类G2:G1{}
//...
类型argument1=GetGenericArgument(类型(G2));//B
类型argument2=GetGenericArgument(类型(G2),1);//A.
//...
静态类型GetGenericArgument(类型类型,int级别=0){
做{
如果(type.IsGenericType&&0==级别--)
返回类型。GetGenericArguments()[0];
type=type.BaseType;
}
while(type!=null);
返回null;
}
能否修改类MyList
以插入返回typeof(MyClass)
的静态GetGenericType
方法?问题是,我可能有不同类型的列表,它们具有不同的继承树,只要它们实现了IList,函数就需要处理所有这些列表。我可以通过使用基本类型来实现这一点,但如果可能的话,我更喜欢“获取集合包含的项目类型”的方法。使用BaseType
有点棘手,由于List
可以作为基类的基础。@史蒂文:但我们有一个强烈的要求,就是我们需要MyList的基类。这个问题还指出List
是基类,所以我们可以简单地给出argumentTypeName=typeof(MyClass)代码>作为答案;-)我刚刚将其插入到代码中,它适用于“直接从列表继承”场景(可能适用于任何场景,我必须检查)。如果我正确理解了这段代码,它就可以工作了,因为由于List实现了IList,任何子类也实现了IList,并且无论继承的多少层将它们分开,它仍然会在接口列表中?
var elementType = (
from iface in myList.GetType().GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() == typeof(IList<>)
select iface.GetGenericArguments()[0])
.Single();
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;
}