我正在做的是通过反射调用方法。在我调用某个方法之前,让我们说它的名字是FooMethod
,我需要创建argument
(我只在运行时知道这个参数的类型)。所以我想使用dynamic
字段来传递argument
的值。
示例:
class SampleClass
{
public string SomeField{get;set;}
}
class Foo
{
void Execute(string methodName, dynamic values)
{
var type = typeof(SampleClass);
var method = type.GetMethod(methodName);
var methodParameterType = method.GetParameters()[0].ParameterType;
var methodParameterProperties = methodParameterType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
//just for example purpose assume that first property name is SomeField
if(values[methodParameterProperties[0].Name] != null)
{
// build argument here
}
}
}
使用:
dynamic a = new {SomeField = "someValue"};
var fooClass = new Foo();
fooClass.Execute("FooMethod",a);//here I'm getting exception
目前我遇到的例外情况:
Cannot apply indexing with [] to an expression of type 'object'
问题: 我该怎么做?有没有办法允许通过索引检查这些值而不创建字典?
答案 0 :(得分:0)
尝试使用ExpandoObject而不是动态。你不能索引它,但你不能创建你的字典。
public void Execute(string methodName, ExpandoObject values)
{
// ...
if(values.Any(x => x.Key == methodParameterProperties[0].Name))
{
var value = values.First(x => x.Key == methodParameterProperties[0].Name).Value;
// build argument here (based on value)
}
}
答案 1 :(得分:0)
您将具有单个字段SomeField
的匿名类的实例分配给a
,然后尝试将其编入索引,就好像它是一个数组一样。那不行。
但是,MethodInfo.Invoke()
接受一个对象数组作为参数,因此根本不需要动态。将values
参数的类型更改为object[]
,然后将其传递给Invoke
。所以:
public class MyClass
{
public void MyMethod(string s)
{
}
}
public object Execute(object obj, string methodName, object[] arguments)
{
Type type = obj.GetType();
MethodInfo methodInfo = type.GetMethod(methodName);
return methodInfo.Invoke(obj, arguments);
}
您还可以向params
添加arguments
说明符,以便可以调用它:
Execute(someObject, "someObjectMethod", arg1, arg2, arg3);
您需要确保传入的参数的类型正确,否则Invoke
会抛出ArgumentException
。此外,如果给定对象没有具有给定名称的方法,GetMethod
将返回null。您可能还需要检查该方法所使用的参数数量,具体取决于您打算如何以及在何处使用此代码。