如何使用 C# 中的反射调用将输入参数作为另一个类对象的方法?(方法给出参数异常)
Posted
技术标签:
【中文标题】如何使用 C# 中的反射调用将输入参数作为另一个类对象的方法?(方法给出参数异常)【英文标题】:How to invoke a method which takes input parameter as another class object using Reflection in C#?(Method gives argument exception) 【发布时间】:2014-06-20 06:27:03 【问题描述】:我以下列方式使用反射: a) 加载程序集 b) 获取所有方法及其各自的参数 c) 调用方法
在调用将输入类型作为原始数据类型(int、double、string 等)的方法时不会遇到问题 我尝试以两种方式调用该方法:
(object)method.Invoke(obj,respar);
其中 respar 是一个输入参数数组
object cu = Activator.CreateInstance(typeof(Customer)) as Customer;
respar.SetValue(cu, i);//i = index
和
(object)type.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Default,null, obj, respar);
在哪里
object obj = Activator.CreateInstance(type,true);//obj
在第一种情况下,我得到一个参数异常错误,在第二种情况下,我得到 Method not found Exception。
例如,如果我调用 GetCustomer(Customer data) 方法,其中 Customer 是一个类,则会引发上述错误。
让我详细解释一下: 有一类 CustomerModel
public class CustomerModel
public string FirstNameget;set;
public string LastName get;set;
和客户类
public class Customer
public CustomerModel GetCustomerDetails(CustomerTable tableobj)
//TODO: Get customer details from tableobj and pass to CustomerModel Obj
我正在尝试通过反射调用此客户类的所有方法。 还有一个类Test:
public class Test
public void GetAllMethodsInassembly()
//Load assembly
//Get all classes
// Foreach Class=> get all methods
//Invoke each method => get result and store in XML file
Customer GetCustomerDetails 中的方法如前所述抛出异常。请提出建议。
【问题讨论】:
请提供有关异常的更多详细信息,最好是整个消息。此客户类型在哪里定义? “客户”类型的对象无法转换为“客户”类型。另一个是:找不到方法'GetCustomer'。客户类在我提到的同一个程序集中定义 您是否在程序集中定义了客户类型?你是如何加载程序集的?您是否正在动态加载您也引用的程序集? 以这种方式加载程序集:code
Assembly assembly = Assembly.LoadFile(您是否尝试过使用 Type.GetMethod
而不是返回具有 Invoke
方法的 MethodInfo
?
更多信息在这里:http://msdn.microsoft.com/en-us/library/6hy0h0z1(v=vs.110).aspx
另一种选择是使用dynamic
。
【讨论】:
【参考方案2】:看起来您已经直接引用了具有 Customer 类型的程序集,并尝试使用 Assembly.LoadFile
动态加载它。我会尝试做这样的事情来获取程序集并调用其中的方法:
Assembly asm = typeof(Customer).Assembly;
foreach (Type type in asm.GetTypes())
if (type.IsClass)
MethodInfo method = type.GetMethod(methodName);
// TODO: create obj
// TODO: create respar
method.Invoke(obj, respar);
如果您坚持动态加载程序集并引用它,则必须了解程序集绑定上下文,否则您将继续遇到同样的问题。
程序集绑定上下文是隔离的内存中程序集缓存。 Load
(“默认”)、LoadFrom
和 LoadFile
都使用不同的上下文。运行时认为在不同上下文中加载的相同程序集的相同类型是不同的。当一个引用的程序集被加载时,它被绑定在默认的“加载”上下文中。
另一个选项可能是使用Assembly.Load
并提供程序集名称。如果程序集是强名称的,则另一个选项可能是更早Load
,然后稍后使用LoadFrom
,因为LoadFrom
将在加载之前检查具有相同名称的程序集是否已经加载到Load
上下文中从指定的文件。
【讨论】:
我正在尝试获取该程序集的所有方法,而不仅仅是客户。那么,当我尝试访问其他类时,如何仅将提供 typeof 的程序集加载为 Customer 或任何其他类。 @Pragyatypeof(Customer).Assembly.GetTypes().Select(t => t.GetMethods())
将为您提供包含 Customer 的程序集中的所有方法。如果您正在引用它,则无需尝试动态加载程序集。
谢谢迈克。但是如果我试图:加载程序集 => 然后获取所有类 => foreach(class) => 调用每个方法。
@Pragya 我想告诉你的是你不必加载程序集。它已经加载了。查看我的编辑。
Mike,所以我必须为每个类创建一个程序集对象?请注意,我将类名作为字符串获取。(来自另一个文件)以上是关于如何使用 C# 中的反射调用将输入参数作为另一个类对象的方法?(方法给出参数异常)的主要内容,如果未能解决你的问题,请参考以下文章