C#如何在运行时参数化泛型List(无需MakeGenericMethod)
运行时动态创建泛型List的解决方案
要在运行时确定泛型参数T并创建强类型List<T>,且避免装箱拆箱、不用MakeGenericMethod,核心是利用Type.MakeGenericType创建具体的泛型类型实例,这是完全可行的,具体步骤和示例如下:
实现步骤
- 获取运行时确定的
T的Type对象(比如从实例example获取,或通过类型名称加载) - 基于泛型
List<>的开放类型,构造出具体的List<T>类型 - 实例化该泛型类型,得到强类型的
List<T>实例 - 将实例存入字典(建议用
Dictionary<Type, object>,键为T的类型,值为对应的List<T>)
代码示例
// 假设example是运行时获取的实例,其类型即为我们要的T Type itemType = example.GetType(); // 构造具体的List<T>类型 Type genericListType = typeof(List<>).MakeGenericType(itemType); // 实例化List<T>,这里转成IList是为了方便基础操作,也可以直接存object IList strongTypedList = (IList)Activator.CreateInstance(genericListType); // 存入字典 var typeToCollectionDict = new Dictionary<Type, object>(); typeToCollectionDict[itemType] = strongTypedList;
操作强类型List(无装箱拆箱)
因为编译时不知道T,直接通过object或IList操作值类型会触发装箱,所以可以用以下两种方式避免:
- 使用dynamic绑定:让运行时自动匹配
List<T>的强类型方法dynamic targetList = typeToCollectionDict[itemType]; targetList.Add(example); // 直接调用List<T>.Add(T),值类型无装箱 - 反射调用强类型方法:精准调用
List<T>的方法,避免装箱MethodInfo addMethod = genericListType.GetMethod("Add", new[] { itemType }); addMethod.Invoke(strongTypedList, new[] { example }); // 无装箱操作
关键说明
- 这种方式创建的
List<T>和编译时直接声明的强类型集合完全一致,存储值类型时不会产生装箱拆箱开销 MakeGenericType是创建泛型类型的具体实例,和你要避免的MakeGenericMethod(调用泛型方法)是完全不同的操作,符合你的要求
内容的提问来源于stack exchange,提问作者Dragnipur
相关产品推荐
相关产品推荐

