【问题标题】:Is it possible to cast a delegate instance into a Lambda expression?是否可以将委托实例转换为 Lambda 表达式?
【发布时间】:2009-01-21 13:35:43
【问题描述】:

这里是我的问题的上下文:

一种常见的技术是将方法的参数声明为 Lambda 表达式而不是委托。这样该方法就可以检查表达式来做一些有趣的事情,比如找出委托实例主体中方法调用的名称。

问题是您失去了 Resharper 的一些智能感知功能。如果方法的参数被声明为委托,Resharper 会在编写对该方法的调用时提供帮助,提示您使用 x => x 语法作为参数值提供给该方法。

所以...回到我的问题,我想做以下事情:

    MethodThatTakesDelegate(s => s.Length);
}

private void MethodThatTakesDelegate(Func<string, object> func)
{
    //convert func into expression
    //Expression<Func<string, object>> expr = "code I need to write"

    MethodThatTakesExpression(expr);
}


private void MethodThatTakesExpression(Expression<Func<string, object>> expr)
{
    //code here to determine the name of the property called against string (ie the Length)
}

【问题讨论】:

  • 我在掩饰this blog entry,它似乎只是直接分配。那不适合你吗?

标签: c# lambda resharper expression-trees


【解决方案1】:

在您使用术语“lambda 表达式”的任何地方,您实际上是指“表达式树”。

lambda 表达式是源代码中的位

parameters => code

例如

x => x * 2

表达式树是System.Linq.Expressions.Expression 类(或者更确切地说是派生类之一)的实例,将代码表示为数据。

编译器将Lambda表达式转换为任一表达式树(或者更确切地说,在执行时生成表达式树的代码)委托实例。

您可以将LambdaExpression(Expression 的子类之一)的实例编译为委托,但不能反过来。

理论上可能可以在某些情况下根据MethodBase.GetMethodBody返回的IL编写这样一个“反编译器”,但目前有各种委托不能用表达式树来表示。表达式树表示 expression 而不是 statement 或语句块 - 因此没有循环、分支(条件除外)、赋值等。我相信这在 .NET 中可能会改变4.0,但我不希望 Microsoft 提供反编译步骤,除非有充分的理由。

【讨论】:

    【解决方案2】:

    我不相信在这里可以实现您想要的。从代码中的 cmets 看来,您正试图捕获在 MethodThatTakesExpression 中进行分配的属性的名称。这需要一个表达式树 lambda 表达式来捕获属性访问的上下文。

    在您将委托传递给 MethodThatTakesDelegate 时,此上下文将丢失。委托仅存储方法地址,而不存储有关方法信息的任何上下文。一旦进行了这种转换,就不可能将其取回。

    为什么这不可能的一个例子是,甚至可能没有命名方法支持委托。可以使用 ReflectionEmit 生成一个没有任何名称且仅存在于内存中的方法。不过可以将其分配给 Func 对象。

    【讨论】:

      【解决方案3】:

      不,这是不可能的。

      【讨论】:

        猜你喜欢
        • 2021-06-19
        • 1970-01-01
        • 2016-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        相关资源
        最近更新 更多