如何枚举传递的方法参数 [英] How to enumerate passed method parameters

查看:610
本文介绍了如何枚举传递的方法参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  private void SomeMethod(int thisValue,string thatValue) 
{
StackTrace stackTrace = new StackTrace();
foreach(stackTrace.GetFrame(0).GetMethod()。GetParameters()中的ParametersInfo pInfo)
{
字符串名称= pInfo.Name;
字符串类型= pInfo.GetType()。ToString();
}
}

但是有什么方法可以得到每个参数?



编辑
我的目标是枚举所有参数并获取其值。
使用LinQ表达式,可以像这样获得参数值:

  private void SomeMethod(int thisValue,string thatValue )
{
object valueOfThis = GetParameterValue(()=> thisValue);
对象valueOfThat = GetParameterValue(()=> thatValue);
}
私有对象GetParameterValue< T>(Expression< Func< T>> expr)
{
var body =((MemberExpression)expr.Body);
return((FieldInfo)body.Member).GetValue((((ConstantExpression)body.Expression).Value);
}

但是我想做的是:

  foreach(thisMethod.GetParameterObjects()中的fooObject o)
{
object someValue = GetParameterValue(()=> fooObject );
}

因此有一种通用的方法可以收集所有参数及其值。

解决方案

更新:



看起来像我通过尝试解释所有内容,使最初的答案过于复杂。这是答案的简短版本。

  private static void SomeMethod(int thisValue,string thatValue)
{
IEnumerable< object>参数= GetParameters(()=> SomeMethod(thisValue,thatValue));
foreach(参数中的var p)
Console.WriteLine(p);
}
私有静态IEnumerable< object> GetParameters(Expression< Action> expr)
{
var body =(MethodCallExpression)expr.Body;
foreach(bodyExpression a in body.Arguments)
{
var test =((FieldInfo)a.Member).GetValue((((ConstantExpression)a.Expression).Value);
收益回报测试;
}
}

这是带有一些解释的加长版本。 / p>

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

  static void Main(string [] args)
{

//第一种方法。
IEnumerable< object>参数= GetParametersFromConstants(()=> SomeMethod(0,零));
foreach(参数中的var p)
Console.WriteLine(p);

//第二种方法。
int thisValue = 0;
string thatValue =零;
IEnumerable< object> parameters2 = GetParametersFromVariables(()=> SomeMethod(thisValue,thatValue));
foreach(参数2中的var p)
Console.WriteLine(p);

Console.ReadLine();
}

私有静态无效SomeMethod(int thisValue,字符串thatValue)
{
Console.WriteLine(thisValue + + thatValue);
}

私有静态IEnumerable< object> GetParametersFromVariables(Expression< Action> expr)
{
var body =(MethodCallExpression)expr.Body;
foreach(bodyExpression a in body.Arguments)
{
var test =((FieldInfo)a.Member).GetValue((((ConstantExpression)a.Expression).Value);
收益回报测试;
}
}

私有静态IEnumerable< object> GetParametersFromConstants(Expression< Action> expr)
{
var body =(MethodCallExpression)expr.Body;
foreach(正文中的常量表达式a。参数)
{
var test = a.Value;
收益回报测试;
}
}

}

注意,如果使用表达式树,则代码在很大程度上取决于传递给该方法的表达式。我已经展示了一种使用常量,一种使用变量。但是当然可以有更多方案。您可以将这两种代码重构为在两种情况下使用单一方法,但是我认为这样可以更好地说明问题。


One can enumerate the called method parameter types/information like this:

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();
  }
}

But is there any way to get the actual object of each parameter?

EDIT: My goal is to enumerate all parameters and get their values. Using LinQ Expressions, one can get the parameter value like so:

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);
}

But what I would like to do is something like:

foreach (fooObject o in thisMethod.GetParameterObjects())
{
  object someValue = GetParameterValue(() => fooObject);
}

And thereby have a generic method for collection all parameters and their values.

解决方案

UPDATE:

Looks like I "overcomplicated" the initial answer by trying to explain everything. Here is the short version of the answer.

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;
    }
}

And here is the long version with some explanations.

In fact, if you use expression trees, you don't need to be inside a method to enumerate its parameters.

    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;
        }
    }

}

Note, that if you use expression trees, your code depends a lot on an expression passed to the method. I have shown one using constants and one using variables. But of course there can be more scenarios. You can refactor this code to use a single method for both cases, but I decided that is illustrates the problem better this way.

这篇关于如何枚举传递的方法参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆