C#中通过反射创建实例时指定带params的重载构造函数(单参数场景)
这个问题我之前也碰到过,反射里的params处理确实有点坑——因为编译器的自动数组包装逻辑在反射场景下不会生效,得手动处理才行。
问题核心原因
params只是C#的编译器语法糖,反射层面只认构造函数的实际参数类型(也就是TestClass[])。如果你直接传单个TestClass实例去匹配构造函数,反射会优先匹配参数类型完全一致的TestClass单参数构造函数,而不会自动把参数包装成数组去匹配params版本。
具体解决方案
下面是完整的可运行代码,我会分步解释关键逻辑:
using System; using System.Reflection; public class TestClass { } public class ConstructorTestClass { public ConstructorTestClass(TestClass singleParam) { Console.WriteLine("调用了TestClass单参数构造函数"); } public ConstructorTestClass(params TestClass[] paramsParam) { Console.WriteLine($"调用了params TestClass[]构造函数,参数个数:{paramsParam?.Length ?? 0}"); } } class Program { static void Main(string[] args) { // 1. 反射创建TestClass实例 Type testClassType = typeof(TestClass); TestClass testInstance = (TestClass)Activator.CreateInstance(testClassType); // 2. 精准获取带params的构造函数:参数类型是TestClass[],不是TestClass Type ctcType = typeof(ConstructorTestClass); ConstructorInfo paramsConstructor = ctcType.GetConstructor(new[] { typeof(TestClass[]) }); if (paramsConstructor == null) { Console.WriteLine("找不到目标构造函数"); return; } // 3. 手动包装调用参数:把单个TestClass实例放进TestClass[]数组,再套一层object[] // 因为Invoke的参数数组,每个元素对应构造函数的一个参数(这里构造函数只有一个TestClass[]类型的参数) object[] invokeParams = new object[] { new TestClass[] { testInstance } }; // 4. 调用构造函数创建实例 ConstructorTestClass ctcInstance = (ConstructorTestClass)paramsConstructor.Invoke(invokeParams); } }
额外小技巧
如果想简化调用,也可以直接用Activator.CreateInstance,但同样要手动包装参数:
// 注意这里的参数是嵌套数组:外层object[]对应构造函数的参数列表,内层TestClass[]对应params的实际参数 ConstructorTestClass ctcInstance = (ConstructorTestClass)Activator.CreateInstance(ctcType, new object[] { new TestClass[] { testInstance } });
内容的提问来源于stack exchange,提问作者mark_h
相关产品推荐
相关产品推荐

