为方法参数赋值

时间:2012-02-29 09:38:20

标签: c# .net reflection methodbase parameterinfo

想象一下具有以下签名的方法:

public void ExampleMethod(string id, object data, 
                          ref object A, ref object B, ref object C)
{
  //...
}

data中的值需要分配给ABC或根本不需要,具体取决于id的值。简而言之,如果id == "A"A = data;

问题在于此方法的主体是由人类输入的,但签名是在运行时生成的。因此,不可能对逻辑进行硬编码,因为在设计时未知有多少参考参数以及它们被称为什么。这段代码可以插入到任意数量的方法中,每个方法可能具有不同的签名,并且必须在每一个方法中都有效。

我知道如何获取当前方法的所有参数,但我无法弄清楚如何为这些参数中的一个赋值。我正在寻找的是以下内容:

public void ExampleMethod(string id, object data, 
                          ref object A, ???????, ref object Z)
{
  MethodBase method = MethodBase.GetCurrentMethod();
  foreach (ParameterInfo parameter in method.GetParameters())
  { 
    if (id == parameter.Name)
    {
      // Problem: assign data to parameter.
      return;
    }
  }
}

1 个答案:

答案 0 :(得分:2)

您无法按名称访问参数,因为您无法真正对变量/参数使用反射。如果这是IL,你可能有一些选择,但在C#中却没有。我的建议是:更改API,可能涉及数组或(可能更好)字典。考虑:

public void ExampleMethod(string id, object data,
        IDictionary<string,object> args) {
    args[id] = data;
}

不确定这是否有帮助...但是你要做的事情并不是真正反映友好的。另一种选择是动态生成此方法,作为构建过程的一部分,或通过IL生成。要么应该没事。所以它本质上可以生成(作为C#或(在运行时)IL):

public void ExampleMethod(string id, object data, 
                          ref object A, ref object B, ref object C)
{
    switch(id) {
        case "A": A = data; break;
        case "B": B = data; break;
        case "C": C = data; break;
        default: /* do something */
    }
}

另一种方法:输入的对象:说你有:

public void ExampleMethod(string id, object data, SomeType obj) {...}

其中obj是具有诸如“A”,“B”,“C”等属性的对象;那么你想要产生的是:

switch(id) {
    case "A": obj.A = data; break;
    case "B": obj.B = data; break;
    case "C": obj.C = data; break;
    default: /* do something */
}

当然可以用反射来完成:

var prop = obj.GetType().GetProperty(id);
prop.SetValue(obj, data, null);

或表现如果至关重要,例如fast-member

var wrapped = ObjectAccessor.Create(obj); 
wrapped[id] = data;
相关问题