从函数创建表达式
本文关键字:表达式 创建 函数 | 更新日期: 2023-09-27 18:25:13
我的代码中有一个Func<TCollection, T>
。我用它来选择某些属性。
在对另一个方法的调用中,我需要Expression<Func<TCollection, T>>
作为参数。
有什么方法可以将Func<TCollection, T>
转换为Expression<Func<TCollection, T>>
吗?
Thanx
您不能基于方法重新创建表达式,因为表达式需要知道原始语句,而不是IL。但是,您可以创建一个Expresson,它可以对您的函数进行方法调用,如:
Func<int> func = () => 1;
Expression<Func<int>> expression = Expression.Lambda<Func<int>>(Expression.Call(func.Method));
然而,请注意,像EF这样的系统不能真正与一起工作
虽然可以创建一个调用委托的表达式树,但它不太可能有用,因为就分析表达式树的代码而言,委托基本上是一个黑盒。假设您正在尝试使用类似LINQ to SQL的东西,那么查询分析器将需要能够窥视您的逻辑以将其转换为SQL,而如果它到达一个普通委托,则无法做到这一点。
您可能应该首先更改委托的代码,以创建表达式树。
您可以这样做:
Func<object, string> func = a => a.ToString();
Expression<Func<object, string>> expr = a => func(a);
但是,您将只得到一个包含对原始Func的方法调用的表达式。你将无法分析函数本身的包含。
您不能从委托(从Func<TCollection, T>
到Expression<Func<TCollection, T>>
)创建表达式,但可以执行oposite。
也就是说,通过编译Expression<Func<TCollection, T>>
转换为Func<TCollection, T>
(.compile
)。
因此,如果您同时需要它们,您可以在函数中使用表达式,如果需要,可以在提供的集合对象上编译并执行它们。
当然,我们必须注意,编译表达式是很慢的。
创建一个类,如下所示;
public class GenericFilter<T> where T : class, new()
{
public Expression<Func<T, bool>> Filter = item => true;
}
用法;
var filter=new GenericFilter<blabla>().Filter.And(x=>...);
filter=filter.And(x=>...);