[英]Set property on a derived class of List<T> instantiated at runtime using reflection
[英]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>
创建接口。
在此先感谢您的帮助!
第一部分是进行比较,您真正要寻找的是字段类型的泛型类型定义的比较。 更改您的 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.