Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反射:泛型列表的非泛型子类中包含的项的类型 公共类MyList:列表_C#_Reflection - Fatal编程技术网

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