我在考虑Expression<Func<>>
和Func<>
之间的区别,并想知道您是否可以将静态方法转换为表达式树,如下所示:
class Program
{
static void Main(string[] args)
{
Func<int, int> t = x => hrm(x);
Func<int, int> t2 = new Func<int, int>(hrm);
// Works as expected:
Expression<Func<int, int>> et = x => hrm(x);
// Brokenness:
Expression<Func<int, int>> et2 = new Func<int, int>(hrm);
}
static int hrm(int x)
{
return x + 9;
}
}
第二个“Func&lt;&gt;”有什么特别之处它不能转换为表达式,当第一个可以?
答案 0 :(得分:4)
我认为你的困惑来自于lambdas可以在C#中表示表达式或委托(具有相同的语法)。所以这段代码:
x => hrm(x)
意味着不同的东西取决于它的写作位置。分配给Func<int, int>
时,它会正常编译以创建Func<int, int>
委托。但是,当分配给表达式时,C#编译器会推迟编译,并且代码段将被解释为表达式。将其与new Func<int, int>(hrm)
进行对比,Func<int, int>
始终返回{{1}}委托。
答案 1 :(得分:1)
我的理解:
lambda可以表示Expression 或委托/ Action / Func
第一个示例有效,因为左侧确保您需要表达式
第二个示例不起作用,因为您创建了一个Func&lt;&gt;明确地在右边。
答案 2 :(得分:1)
只有lambda表达式可以转换为表达式树。这就是你的第二个选项无法编译的原因。
您可以创建表达式树来表示hrm()
的调用 - 但它可以通过lambda或手动创建AST。此外,在任何情况下,hrm()
的身体都不能作为表达树 - 如果这是你想要做的那样。
答案 3 :(得分:0)
我建议您查看这两篇博文:Expression Tree Basics by Charlie Calvert和我自己的帖子Generating Dynamic Methods with Expression Trees in Visual Studio 2010。
这些应该可以让您对表达式树语法以及它们可以做什么和不可以做什么有所了解。