我是一位帮助翻译的助手。
有一个小问题需要大家帮忙解决。
我想要做以下事情:
Type[] classes = new Type[]{ Class1, Class2 };
foreach(Type t in classes){
List<t> list = new List<t>();
}
有没有一些方法可以做到这一点?
在运行时无法将类型转换为泛型类型,因为泛型中的类型需要在编译时解析。
您可以使用反射以动态方式创建泛型类型,但除非硬编码转换,否则返回的只是一个对象。
我无法真正了解您想要什么,我同意评论中的观点,这是一个XY问题。我倾向于做出放肆的声明,即这里试图解决某个设计问题,而不是直接解决设计问题,或者直接问您想要实现什么。
您可以使用以下代码创建类型,然后使用dynamic
类型来鸭子类型 List<T>
的各个成员,而不需要知道/关心它是列表还是T
是什么:
using System;
using System.Collections.Generic;
namespace ConsoleApplication61
{
class Program
{
static void Main(string[] args)
{
dynamic o = CreateGeneric(typeof(List<>), typeof(int));
o.Add(1);
Console.WriteLine(o[0]);
Console.Read();
}
public static object CreateGeneric(Type generic, Type innerType, params object[] args)
{
System.Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
return Activator.CreateInstance(specificType, args);
}
}
}
Add
方法和索引器。DLR在运行时处理类型和鸭子类型 - 例如,知道1
是一个int
。CreateGeneric
方法。int
传递给隐藏在dynamic
中的List<int>
。
dynamic
在应用程序中没有被使用过,在测试代码库中也只用了几次。这并不是说“不要使用”,而是说“大多数情况下,你不需要它”。dynamic
很不错,但调用 o.Add(1)
假设 o
是一个 List<int>
,那么你可以一样地转换为 List<int>
而不是使用 dynamic
。实际上,如果动态类型是 List<long>
,List<short>
等,则 o.Add(1)
也可以工作,使其比特定列表的转换略具灵活性,因此在特殊场景下,它还是有些用处的,例如当你有不同宽度的数字列表时。 - Martin Liversage1
是作为参数在其他地方提供的对象会发生什么 - DLR 是否会识别底层类型,或者它是否不关心并且仍然会尝试。在我看来,这种情况非常具体,如果他们正在动态创建特定列表,我只能假设它们的使用也是特定的。 - Adam Houldsworthforeach(Type t in classes)
{
var listType = typeof(List<>).MakeGenericType(t);
var instance = Activator.CreateInstance(listType);
}
t
? - Adam Houldsworthpublic static object CreateGeneric(Type generic, Type innerType, params object[] args)
{
System.Type specificType = generic.MakeGenericType(new System.Type[] { innerType });
return Activator.CreateInstance(specificType, args);
}
然后像这样使用:
var o = CreateGeneric(typeof(List<>), t);
很抱歉,要添加项目,您需要按以下方式执行(其中item是您要添加的项目)。
MethodInfo addMethod = o.GetType().GetMethod("Add");
addMethod.Invoke(o, new object[] { item.ToType(t) });
o
强制转换为适当的 List<T>
吗?我对此非常感兴趣。 - Michal B.Type[] classes = new Type[] { typeof(A), typeof(B) };
foreach (Type t in classes)
{
Type genericType = typeof(List<>).MakeGenericType(t);
var list = Activator.CreateInstance(genericType);
}
如果您想将对象保留在一个列表中,那么它们可能有一些共同点。
在这种情况下,我认为,就像L.B在评论中提到的那样,您在这里问了一个错误的问题。
可能是您的设计问题。考虑这些类型,看看它们有什么共同点,并考虑从一个基本类型派生或使两者实现相同的接口。在这种情况下,您将能够实例化一个基本类型/接口对象的列表并使用它们。
只是为了给您一个开头:
abstract class Vehicle {
public int NumberOfWheels { get; set; }
}
class Car : Vehicle
{
public Car()
{
NumberOfWheels = 4;
}
}
class Bicycle : Vehicle
{
public Bicycle()
{
NumberOfWheels = 2;
}
}
static void Main(string[] args)
{
var v1 = new Car();
var v2 = new Bicycle();
var list = new List<Vehicle>();
list.Add(v1);
list.Add(v2);
foreach (var v in list)
{
Console.WriteLine(v.NumberOfWheels);
}
Console.ReadKey();
}
foreach
的用途是什么? - V4Vendetta