【发布时间】:2018-04-13 17:12:38
【问题描述】:
例如,这里有一些通过反射创建List<int> 的代码(是的,我知道有一些函数可以从数组转换为列表,问题不在于该解决方案,而是关于在不知道类型的情况下使用反射.
public static T Convert<T>(int[] src)
{
Type genericClassType = typeof(T);
Type[] typeParameters = genericClassType.GetGenericArguments();
Type genericTypeDef = genericClassType.GetGenericTypeDefinition();
Type constructedClass = genericTypeDef.MakeGenericType(typeParameters);
T arrayLike = (T)Activator.CreateInstance(constructedClass);
System.Reflection.MethodInfo method = arrayLike.GetType().GetMethod("Add", typeParameters);
foreach (int value in src) {
method.Invoke(arrayLike, new []{(object)value});
}
return arrayLike;
}
所以我可以这样称呼它
int[] src = {4, 5, 6};
List<int> copy = Convert<List<int>>(src);
但我也希望能够这样称呼它
int[] src = {4, 5, 6};
Stack<int> copy = Convert<Stack<int>>(src);
int[] src = {4, 5, 6};
Queue<int> copy = Convert<Queue<int>>(src);
但我不能,因为例如 Stack 没有 Add 方法
实际上,我正在做一些反序列化工作并试图使其成为通用或半通用的。源数据没有类型信息。它只是一个整数数组,但是当调用反序列化代码时,我知道我希望它是什么类型List、Stack、Queue 等等......所以,是否可以一般转换为给定类型或将我必须为每种类型的泛型编写自定义代码?
我确定在某种程度上List、Stack、Queue 是不同的,但我的 C/C++/Assembly 程序员看到给定一个 int 数组和所需类型,所有信息都可以重构给定只有一个通用的构造函数(已经出现在上面的代码中)。
【问题讨论】:
-
请注意,
Stack、Queue和List都有带有IEnumerable<T>的构造函数,您可以传递数组。 -
你知道你在编译时反序列化成的类型(如 List)还是只在运行时?
标签: c# generics collections