鉴于以下代码,
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 = Execute(() => _service.SomeMethod3( someParm1, someParm2));
}
从Execute方法中,是否可以检查“methodParam”并提取或确定匿名函数体内的参数个数?例如,是否可以从Execute方法中确定someParam1和someParam2的值?
答案 0 :(得分:6)
您可以使用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()();
}
参数变量将是ParameterInfo
个对象的数组,它将包含您需要的信息。最后,Compile方法实际上将Expression转换为可执行委托。 C#编译器还允许您使用标准lambdas / anonymous方法调用带有委托的方法的常规约定来调用此方法。
编辑:
我还注意到你想要一种方法来获得someParam1和someParam2的实际值。以下是您可以这样做的方法:
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;
}
现在在执行方法中,如果你这样做:
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()();
}
然后值将是一个对象[],其中包含传入的所有实际值。
答案 1 :(得分:0)
任何methodParam
来电都没有参数
代码:() => _service.SomeMethod1()
基本上“指向”另一个返回T
的函数
() => _service.SomeMethod1()
相当于:
() => { return _service.SomeMethod1(); }
编辑以实际回答问题(愚蠢的我):
试试:
T result2 = Execute(() => { [BreakPoint]return _service.SomeMethod3(someParm1, someParm2) } );
答案 2 :(得分:0)
不太可能。 Execute
方法传递一个委托 - 在这种情况下是对匿名函数的引用。您要问的是Execute
方法查看该函数的代码并确定它正在做什么。
这类似于我试图在运行时查看Random.Next
方法以查看它调用的方法。
答案 3 :(得分:0)
我认为这根本不回答这个问题。这实际上执行委托方法并将结果返回到values []对象。我相信海报在询问,我也在问如何在委托方法中获取参数的值。