有没有办法像这样使用动态字段?

时间:2014-11-17 10:51:17

标签: c# dynamic reflection

我正在做的是通过反射调用方法。在我调用某个方法之前,让我们说它的名字是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'

问题: 我该怎么做?有没有办法允许通过索引检查这些值而不创建字典?

2 个答案:

答案 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。您可能还需要检查该方法所使用的参数数量,具体取决于您打算如何以及在何处使用此代码。