简体   繁体   English

如何在c#中确定匿名函数参数?

[英]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 = Execute(() => _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? 从Execute方法,是否可以检查“methodParam”并提取或确定匿名函数体内的参数数量? For example is it possible to determine the values of someParam1 and someParam2 from within the Execute method? 例如,是否可以从Execute方法中确定someParam1和someParam2的值?

You can do it using the Expression API: 您可以使用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. 参数变量将是一个ParameterInfo对象数组,它将包含您需要的信息。 Finally, the Compile method actually converts the Expression to an executable delegate. 最后,Compile方法实际上将Expression转换为可执行委托。 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. C#编译器还允许您使用标准lambdas / anonymous方法调用带有委托的方法的常规约定来调用此方法。

EDIT: 编辑:

I also just noticed that you wanted a way to get the actual value of the someParam1 and someParam2. 我还注意到你想要一种方法来获得someParam1和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: 所以现在在你的execute方法中,如果你这样做:

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. 那么值将是一个对象[],其中包含传入的所有实际值。

I don't think this answers the question at all. 我认为这根本不回答这个问题。 This actually executes the delegate method and returns the results into the values[] object. 这实际上执行委托方法并将结果返回到values []对象。 I believe the poster was asking and I am asking as well how to get the values of the parameters within the delegate method. 我相信海报在询问,我也在问如何在委托方法中获取参数的值。

There are no params in any of the methodParam calls. 任何methodParam调用中都没有params。
The code: () => _service.SomeMethod1() basically "points" to another function which returns T . 代码: () => _service.SomeMethod1()基本上“指向”另一个返回T函数。
() => _service.SomeMethod1() is equivalent to: () => _service.SomeMethod1()相当于:
() => { 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. Execute方法传递一个委托 - 在本例中是对匿名函数的引用。 What you're asking is for the Execute method to look inside the code for that function and determine what it's doing. 您要问的是Execute方法查看该函数的代码并确定它正在做什么。

That's akin to me trying to peek inside the Random.Next method at runtime to see what methods it calls. 这类似于我试图在运行时查看Random.Next方法以查看它调用的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM