通过反射调用带有参数的泛型方法时,无法将 System.Int32 类型的对象转换为 System.Object[]
Unable to cast object of type System.Int32 to System.Object[] when calling generic method with parameters via reflection
别说我有一些 class 有两个构造函数(没有参数和有参数):
public class Employee
{
private int Salary = 0;
public Employee()
{
Salary = 100;
}
public Employee(int newSalary)
{
Salary = newSalary;
}
}
我有一些静态助手 class,它们具有调用构造函数的通用方法:
public static class GenericClassCreator
{
public static T CreateClassNoParams<T>()
where T : class, new()
{
return new T();
}
public static T CreateClassWithParams<T>(params object[] args)
where T : class
{
return (T)Activator.CreateInstance(typeof(T), args);
}
}
让我们假设我有 class 的类型,我需要构建(typeof(Employee) 在这种特殊情况下)并使用以下代码调用它的构造函数:
var method1 = typeof(GenericClassCreator).GetMethod("CreateClassNoParams");
var generic1 = method1.MakeGenericMethod(typeof(Employee));
var employee1 = generic1.Invoke(null, null);
var method2 = typeof(GenericClassCreator).GetMethod("CreateClassWithParams");
var generic2 = method2.MakeGenericMethod(typeof(Employee));
var employee2 = generic2.Invoke(null, new object[] { (object)500 });
获取employee1(通过无参构造函数)即可。但是获取 employee2(通过带参数的构造函数)抛出异常:
Unable to cast object of type System.Int32 to System.Object[]
就算我变了
generic.Invoke(null, new object[] { (object)500 });
至
generic.Invoke(null, new object[] { new object() });
抛出异常
Unable to cast object of type System.Object to System.Object[]
那么我的代码有什么问题?
您的方法需要一个 object[]
作为参数。 MethodInfo.Invoke
需要包含所有参数的 object[]
。这意味着您需要一个包含另一个 object[]
:
的 object[]
var employee2 = generic2.Invoke(null, new object[] { new object[] { 500 } });
让您感到困惑的部分是:Invoke
需要一个对象数组来存储您调用的方法的参数。现在它获取该对象数组,并使用其中的值来调用该方法。
但是,您的方法本身也需要 object[]
才能工作。现在外面的 object[]
已经不存在了,只有一个 int
来调用你的方法。您必须用第二个数组包裹第一个数组以符合您的方法签名。
generic2.Invoke(null, new object[] { new object[] { (object)500 } });
试试这个
generic2.Invoke(null, new object[] { new object[] { 500 } });
别说我有一些 class 有两个构造函数(没有参数和有参数):
public class Employee
{
private int Salary = 0;
public Employee()
{
Salary = 100;
}
public Employee(int newSalary)
{
Salary = newSalary;
}
}
我有一些静态助手 class,它们具有调用构造函数的通用方法:
public static class GenericClassCreator
{
public static T CreateClassNoParams<T>()
where T : class, new()
{
return new T();
}
public static T CreateClassWithParams<T>(params object[] args)
where T : class
{
return (T)Activator.CreateInstance(typeof(T), args);
}
}
让我们假设我有 class 的类型,我需要构建(typeof(Employee) 在这种特殊情况下)并使用以下代码调用它的构造函数:
var method1 = typeof(GenericClassCreator).GetMethod("CreateClassNoParams");
var generic1 = method1.MakeGenericMethod(typeof(Employee));
var employee1 = generic1.Invoke(null, null);
var method2 = typeof(GenericClassCreator).GetMethod("CreateClassWithParams");
var generic2 = method2.MakeGenericMethod(typeof(Employee));
var employee2 = generic2.Invoke(null, new object[] { (object)500 });
获取employee1(通过无参构造函数)即可。但是获取 employee2(通过带参数的构造函数)抛出异常:
Unable to cast object of type System.Int32 to System.Object[]
就算我变了
generic.Invoke(null, new object[] { (object)500 });
至
generic.Invoke(null, new object[] { new object() });
抛出异常
Unable to cast object of type System.Object to System.Object[]
那么我的代码有什么问题?
您的方法需要一个 object[]
作为参数。 MethodInfo.Invoke
需要包含所有参数的 object[]
。这意味着您需要一个包含另一个 object[]
:
object[]
var employee2 = generic2.Invoke(null, new object[] { new object[] { 500 } });
让您感到困惑的部分是:Invoke
需要一个对象数组来存储您调用的方法的参数。现在它获取该对象数组,并使用其中的值来调用该方法。
但是,您的方法本身也需要 object[]
才能工作。现在外面的 object[]
已经不存在了,只有一个 int
来调用你的方法。您必须用第二个数组包裹第一个数组以符合您的方法签名。
generic2.Invoke(null, new object[] { new object[] { (object)500 } });
试试这个 generic2.Invoke(null, new object[] { new object[] { 500 } });