繁体   English   中英

实例化一个 List 的派生类<T>在运行时使用反射

[英]Instantiate a derived class of List<T> at runtime using reflection

我有一个通用class MyList<T> : MyBaseClass, IList<T>它接受未知数量的未知元素类型。
在其他地方,我声明了一些自定义列表没有实例化它们(由于一些一般限制,这是必须的):

MyList<MyObjectType1> type1List1, type1List2,... ;
MyList<MyObjectType2> type2List1, type2List2,... ;

我想在运行时使用反射实例化这些自定义列表:

foreach (FieldInfo field in this.GetType().GetFields())
{
   if (field.FieldType == typeof(MyList<>)) // this condition is **NEVER** passed!
   {
      MyList<>valueToSet = new MyList<>(); // does not work, needs type
      MyList<T>valueToSet = new MyList<T>(); // does not work, there's no T
      MyList<...?...>valueToSet = new MyList<...?...>(); // how can i put here the type?
      field.SetValue(this, valueToSet);
      ...
   }
}

我遇到的问题是,因此在每个声明的列表中使用的对象类型在运行时之前都是未知的,我找不到在我的代码中用于实例化MyList<...?...>valueToSet = new MyList<...?...>()的表达式MyList<...?...>valueToSet = new MyList<...?...>() ,以及令人惊讶的(至少对我而言)表达式if (field.FieldType == typeof(MyList<>))从未通过。

以防万一,请注意,由于某些类依赖性和约束,我无法为MyList<T>创建接口。

在此先感谢您的帮助!

编辑:
感谢MikeSweeper我可以完全解决这个问题

第一部分是进行比较,您真正要寻找的是字段类型的泛型类型定义的比较。 更改您的 if 语句以使用 GetGenericTypeDefinition 来检查:

if (field.FieldType.IsGenericType && field.FieldType.GetGenericTypeDefinition() == typeof(MyList<>))

接下来,您必须构造一个您不知道的类型的实例,Activator.CreateInstance 通常是执行此操作的最简单方法:

var list = Activator.CreateInstance(field.FieldType);
field.SetValue(this, list);

现在我注意到的一件事是我们正在当前对象上设置字段。 这有点不寻常。 这是为什么? 你在编译时不知道所有这些类型吗?

在您的用例中可以使用MyList<dynamic>吗?

例如

type1List1 = new List<dynamic>(); 
type1List1.Add(new MyObjectType1()); 
MyObjectType1 element = type1List1.ElementAt(0);

基本上 dynamic 是一种特殊类型,可以具有任何属性 - 有效地获得了一些更松散类型的语言(如 JavaScript 到 C# 中)的一些好处。 您可以向 MyList 添加任何类型的对象。 您只需要在代码中手动跟踪每个类型中的类型,并确保在您希望使用它们时知道您期望的是什么类型

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM