【问题标题】:Capture incoming Argument Values in KeyValuePair Array在 KeyValuePair 数组中捕获传入的参数值
【发布时间】:2010-10-24 10:13:22
【问题描述】:

我想知道如何在数组中获取方法的传入参数。或者只是动态地检索我的参数的值。

意思是这样的称呼:

MyMethod(10, "eleven");

对于方法:

void MyMethod(int Test, str Test2) {}

将解析为如下数组:

{{"Test" => 10}, {"Test2", "eleven"}}

如果我能通过反射实现这一点会更好。例如。以某种方式使用 StackTrace。

【问题讨论】:

  • 是的。你不会得到它们。您将仅获得参数名称。所以我认为这行不通。
  • @Robin:你看到我的实现来轻松地向字典添加参数了吗?我编辑了我的答案。这有帮助吗?

标签: c# reflection arguments


【解决方案1】:

也许这不是您想要的,但我发现我可以使用马特汉密尔顿建议的方法的变体并利用匿名类型参数的隐式命名来为我的情况做出合理的折衷:

public void MyMethod(string arg1, bool arg2, int arg3, int arg4)
{
    var dictionary = new PropertyDictionary(new 
    { 
        arg1, arg2, arg3, arg4 
    });
}

public class PropertyDictionary : Dictionary<string, object>
{
    public PropertyDictionary(object values)
    {
        if(values == null)
            return;

        foreach(PropertyDescriptor property in TypeDescriptor.GetProperties(values))
            Add(property.Name, property.GetValue(values);   
    }
}    

正如我所说,它可能对您的情况没有帮助,但在我的情况下(单元测试一种处理 XML 的方法)它非常有用。

【讨论】:

    【解决方案2】:

    我想,你要找的东西不存在。您可以拥有的最接近的是参数:

    MyMethod(params object[] args) 
    {
        // if you have to do this, it's quite bad:
        int intArg = (int)args[0];
        string stringArg = (string)arg[1]:
    }
    
    // call with any number (and type) of argument
    MyMethod(7, "tr");
    

    没有编译时类型检查,因此它不是处理参数的万能方法。但是如果你的论点动态的,它可能是一个解决方案。


    编辑:有另一个想法:

    您需要将所有参数手动放入列表/字典中。您可以编写一个帮助类来允许以下操作:

    MyMethod(int arg1, string arg2) 
    {
        Arguments.Add(() => arg1);
        Arguments.Add(() => arg2);
        //
    }
    

    助手看起来像这样

    public static void Add<T>(Expression<Func<T>> expr)
    {
        // run the expression to get the argument value
        object value = expr.Compile()();
        // get the argument name from the expression
        string argumentName = ((MemberExpression)expr.Body).Member.Name;
    
        // add it to some list:
        argumentsDic.Add(argumentName, value);
    }
    

    【讨论】:

    • 问题是我正在使用 WebServices。我想捕获正在调用的传入参数...
    • 我有另一个想法......请参阅我的答案中的新部分。
    【解决方案3】:

    由于该方法使用命名参数,为什么不能直接用它们的名称和值显式填充字典?由于您已经知道它们,因此使用反射来获取它们的名称没有什么意义。

    如前所述,params 关键字可用于定义具有可变数量参数的方法,但根据定义,这些参数是无名的。

    我不确定你在问什么,按照你解释的方式,有什么意义。也许您可以进一步详细说明?

    【讨论】:

      【解决方案4】:

      我知道的一种方法(不确定它现在是否是唯一的方法,但它曾经是)是使用面向方面的编程(AOP),尤其是拦截。手动滚动它有点痛苦,但有一些出色的工具可以提供帮助。 PostSharp 就是这样一种工具:http://www.postsharp.org/

      【讨论】:

        【解决方案5】:

        好问题 (+1)。我想这就是你需要的 -

        MethodBase mb = MethodBase.GetCurrentMethod();
        ParameterInfo[] pi = mb.GetParameters();
        

        【讨论】:

        • 但是你不会得到参数值,对吧?
        • 我实际上已经尝试过了。但我只得到参数的名称,而不是传入/当前调用的值。
        【解决方案6】:

        您最好的选择是使用匿名类型,如this example 所示。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-01-03
          • 2019-12-21
          • 2014-07-18
          • 2011-04-06
          • 1970-01-01
          相关资源
          最近更新 更多