How to enumerate passed method parameters
c#, reflection
Solution
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.
Problem
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.