做什么Expression<T>
?
我已经看到它以类似于以下的方法使用:
private Expression<Func<MyClass,bool>> GetFilter(...)
{
}
不能直接退货Func<MyClass,bool>
吗?
由于 < 和 > 符号,Google 和 SO 搜索失败了。
如果TDelegate
表示一个委托类型,则Expression<TDelegate>
表示一个 lambda 表达式,该表达式可以转换为TDelegate
表达式树的类型的委托。这允许您以编程方式检查 lambda 表达式以提取有用信息。
例如,如果您有
var query = source.Where(x => x.Name == "Alan Turing");
如果将其表示为表达式树,则x => x.Name == "Alan Turning"
可以以编程方式对其进行检查,但如果将其视为委托,则不能那么多。这在 LINQ 提供程序将遍历表达式树以将 lambda 表达式转换为不同表示的情况下特别有用。例如,LINQ to SQL 会将上述表达式树转换为
SELECT * FROM COMPUTERSCIENTIST WHERE NAME = 'Alan Turing'
它可以做到这一点,因为 lambda 表达式表示为一棵树,其节点可以被遍历和检查。
是的,Func<>
可以用来代替表达式。表达式树的实用性在于它使远程 LINQ 提供程序(例如 LINQ to SQL)能够提前查看需要哪些语句才能使查询运行。换句话说,将代码视为数据。
//run the debugger and float over multBy2. It will be able to tell you that it is an method, but it can't tell you what the implementation is.
Func<int, int> multBy2 = x => 2 * x;
//float over this and it will tell you what the implmentation is, the parameters, the method body and other data
System.Linq.Expressions.Expression<Func<int, int>> expression = x => 2 * x;
在上面的代码中,您可以通过调试器比较可用的数据。我邀请你这样做。您会看到 Func 提供的信息非常少。用 Expressions 再试一次,你会看到很多信息,包括运行时可见的方法体和参数。这就是表达式树的真正威力。