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

发布于 2024-12-09 07:09:58 字数 529 浏览 0 评论 0原文

给定以下代码,

    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 的值?

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? For example is it possible to determine the values of someParam1 and someParam2 from within the Execute method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

总攻大人 2024-12-16 07:09:58

您可以使用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# 编译器还允许您使用采用委托的调用方法的常规约定以及标准 lambda/匿名方法来调用此方法。

编辑:

我还刚刚注意到您想要一种方法来获取 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()();
}

那么值将是一个 object[] ,其中包含传入的所有实际值。

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.

汹涌人海 2024-12-16 07:09:58

任何 methodParam 调用中都没有参数。
代码: () => _service.SomeMethod1()
基本上“指向”另一个返回 T 的函数。
<代码>() => _service.SomeMethod1() 相当于:
<代码>() => { return _service.SomeMethod1(); }

编辑以实际回答问题(愚蠢的我):
尝试:

T result2 =
   Execute(() =>
   {
      [BreakPoint]return _service.SomeMethod3(someParm1, someParm2)
   }
);

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)
   }
);
罪#恶を代价 2024-12-16 07:09:58

这不太可能。 Execute 方法传递一个委托——在本例中是对匿名函数的引用。您要求的是 Execute 方法查看该函数的代码并确定它在做什么。

这类似于我试图在运行时查看 Random.Next 方法内部以查看它调用了哪些方法。

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.

挖鼻大婶 2024-12-16 07:09:58

我认为这根本不能回答问题。这实际上执行了委托方法并将结果返回到values[]对象中。我相信发帖者在问,我也在问如何获取委托方法中的参数值。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文