如何枚举传递的方法参数 [英] How to enumerate passed method parameters
问题描述
可以枚举如下所示的被调用方法的参数类型/信息:
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屋!