如何枚举传递的方法参数

Mag*_*son 11 c# reflection

可以枚举被调用的方法参数类型/信息,如下所示:

private void SomeMethod(int thisValue, string thatValue)
{
  StackTrace stackTrace = new StackTrace();
  foreach (ParameterInfo pInfo in stackTrace.GetFrame(0).GetMethod().GetParameters())
  {
    string name = pInfo.Name;
    string type = pInfo.GetType().ToString();
  }
}
Run Code Online (Sandbox Code Playgroud)

但有没有办法得到每个参数的实际对象?

编辑:我的目标是枚举所有参数并获取它们的值.使用LinQ表达式,可以获得如下参数值:

private void SomeMethod(int thisValue, string thatValue)
{
  object valueOfThis = GetParameterValue(() => thisValue);
  object valueOfThat = GetParameterValue(() => thatValue);
}
private object GetParameterValue<T>(Expression<Func<T>> expr)
{
  var body = ((MemberExpression)expr.Body);
  return ((FieldInfo)body.Member).GetValue(((ConstantExpression)body.Expression).Value);
}
Run Code Online (Sandbox Code Playgroud)

但我想做的是:

foreach (fooObject o in thisMethod.GetParameterObjects())
{
  object someValue = GetParameterValue(() => fooObject);
}
Run Code Online (Sandbox Code Playgroud)

因此,有一个通用的方法来收集所有参数及其值.

Ale*_*ina 9

更新:

看起来我试图解释一切都"过于复杂"了最初的答案.这是答案的简短版本.

private static void SomeMethod(int thisValue, string thatValue)  
{ 
    IEnumerable<object> parameters = GetParameters(() => SomeMethod(thisValue, thatValue)); 
    foreach (var p in parameters) 
        Console.WriteLine(p); 
}
private static IEnumerable<object> GetParameters(Expression<Action> expr)
{
    var body = (MethodCallExpression)expr.Body;
    foreach (MemberExpression a in body.Arguments)
    {
        var test = ((FieldInfo)a.Member).GetValue(((ConstantExpression)a.Expression).Value);
        yield return test;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是长版本,有一些解释.

实际上,如果使用表达式树,则不需要在方法内部枚举其参数.

    static void Main(string[] args)
    {

        // First approach.
        IEnumerable<object> parameters = GetParametersFromConstants(() => SomeMethod(0, "zero"));
        foreach (var p in parameters)
            Console.WriteLine(p);

        // Second approach.
        int thisValue = 0;
        string thatValue = "zero";
        IEnumerable<object> parameters2 = GetParametersFromVariables(() => SomeMethod(thisValue, thatValue));
        foreach (var p in parameters2)
            Console.WriteLine(p);

        Console.ReadLine();
    }

    private static void SomeMethod(int thisValue, string thatValue) 
    {
        Console.WriteLine(thisValue + " " + thatValue);
    }      

    private static IEnumerable<object> GetParametersFromVariables(Expression<Action> expr)
    {
        var body = (MethodCallExpression)expr.Body;
        foreach (MemberExpression a in body.Arguments)
        {               
            var test = ((FieldInfo)a.Member).GetValue(((ConstantExpression)a.Expression).Value);
            yield return test;
        }
    }

    private static IEnumerable<object> GetParametersFromConstants(Expression<Action> expr)
    {
        var body = (MethodCallExpression)expr.Body;
        foreach (ConstantExpression a in body.Arguments)
        {
            var test = a.Value;
            yield return test;
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

请注意,如果使用表达式树,则代码很大程度上取决于传递给方法的表达式.我展示了一个使用常量,一个使用变量.但当然可以有更多场景.您可以重构此代码以针对这两种情况使用单个方法,但我认为这样可以更好地说明问题.