How to determine anonymous function parameters in c#?
Given the following code,
public T Execute<T>(Func<T> methodParam)
{
return methodParam ();
}
public void CallMethodsAnonymously<T>()
{
T result = Execute(() => _service.SomeMethod1());
T result1 = Execute(() => _service.SomeMethod2(someParm1));
T result2 = Execut开发者_JAVA技巧e(() => _service.SomeMethod3( someParm1, someParm2));
}
From the Execute method, is it possible to inspect “methodParam” and extract or determine the number of parameters within the anonymous function body? For example is it possible to determine the values of someParam1 and someParam2 from within the Execute method?
You can do it using the Expression
API:
public static T Execute<T>(Expression<Func<T>> methodParam)
{
var methodCallExpression = methodParam.Body as MethodCallExpression;
var method = methodCallExpression.Method;
var parameters = method.GetParameters();
return methodParam.Compile()();
}
The parameters variable will be an array of ParameterInfo
objects which will contain the information you need. Finally, the Compile method actually converts the Expression to an executable delegate. The C# compiler also allows you to call this method with the regular conventions of calling methods that take delegates, with the standard lambdas/anonymous methods.
EDIT:
I also just noticed that you wanted a way to get the actual value of the someParam1 and someParam2. Here's how you can do that:
private static object GetValue(Expression expression)
{
var constantExpression = expression as ConstantExpression;
if (constantExpression != null)
{
return constantExpression.Value;
}
var objectMember = Expression.Convert(expression, typeof(object));
var getterLambda = Expression.Lambda<Func<object>>(objectMember);
var getter = getterLambda.Compile();
return getter();
}
private static object[] GetParameterValues(LambdaExpression expression)
{
var methodCallExpression = expression.Body as MethodCallExpression;
if (methodCallExpression != null)
{
return methodCallExpression.Arguments.Select(GetValue).ToArray();
}
return null;
}
So now in your execute method, if you do this:
public static T Execute<T>(Expression<Func<T>> methodParam)
{
var methodCallExpression = methodParam.Body as MethodCallExpression;
var method = methodCallExpression.Method;
var parameters = method.GetParameters();
var values = GetParameterValues(methodParam);
return methodParam.Compile()();
}
then the values will be an object[] with all the actual values that were passed in.
There are no params in any of the methodParam
calls.
The code: () => _service.SomeMethod1()
basically "points" to another function which returns T
.
() => _service.SomeMethod1()
is equivalent to:
() => { return _service.SomeMethod1(); }
Edit to actually answer the question (silly me):
Try:
T result2 = Execute(() => { [BreakPoint]return _service.SomeMethod3(someParm1, someParm2) } );
It's unlikely. The Execute
method is passed a delegate--in this case a reference to an anonymous function. What you're asking is for the Execute
method to look inside the code for that function and determine what it's doing.
That's akin to me trying to peek inside the Random.Next
method at runtime to see what methods it calls.
I don't think this answers the question at all. This actually executes the delegate method and returns the results into the values[] object. I believe the poster was asking and I am asking as well how to get the values of the parameters within the delegate method.
精彩评论