我必须创建一个表达式树来表示用户输入的查询,这有点难度。由于我没有时间创建所有可能的用户输入案例,因此我认为表达式树会帮助我解决这个问题。表达式与谓词问题
大多数情况下,它有。但是,我有点难住。我在下面的代码中试图用动态创建的表达式来执行List.Find。表达,总之,是这样的:
list.Find(m => m.ListOfStrings.Exists(s => s == "cookie"));
其中m为
class MyClass
{
public List<string> ListOfStrings { get; set; }
}
竟然创造
s => s == "cookie"
与表情,没有任何问题,我已经得到了。我也宣布MethodInfo的对已存在
var existsMethod = typeof(MyClass)
.GetProperty("ListOfStrings")
.PropertyType
.GetMethod("Exists");
我唯一的问题是建立一个表达的lambda来调用该方法作为一个参数,像这样
var findLambda = Expression.Lambda(
Expression.Call(
Expression.Property(
Expression.Parameter(typeof(MyClass), "m"),
typeof(MyClass).GetProperty("ListOfStrings")),
existsMethod,
existsLambda),
Expression.Parameter(
typeof (MyClass),
"m"));
它给出了一个可以理解的异常
Expression of type 'System.Func`2[System.String,System.Boolean]' cannot be used for parameter of type 'System.Predicate`1[System.String]' of method 'Boolean Exists(System.Predicate`1[System.String])'
我怎么能克服这个?
全码:
private class MyClass
{
public List<string> ListOfStrings { get; set; }
}
public void SomeMethod()
{
var myObject = new MyClass();
myObject.ListOfStrings = new List<string>();
myObject.ListOfStrings.Add("cookie");
myObject.ListOfStrings.Add("biscuit");
List<MyClass> list = new List<MyClass>();
list.Add(myObject);
var existsLambda = Expression.Lambda(
Expression.Equal(
Expression.Parameter(typeof(string), "s"),
Expression.Constant("cookie")),
Expression.Parameter(typeof(string), "s"));
var existsMethod = typeof(MyClass).GetProperty("ListOfStrings").PropertyType.GetMethod("Exists");
var findLambda = Expression.Lambda(
Expression.Call(
Expression.Property(
Expression.Parameter(typeof(MyClass), "m"),
typeof(MyClass).GetProperty("ListOfStrings")),
existsMethod,
existsLambda),
Expression.Parameter(
typeof (MyClass),
"m"));
list.Find((Predicate<MyClass>)findLambda.Compile());
}
我知道,“动态”用户输入的是一个有点Linq中的挑战,但如果用户只需指定要过滤的字段的不同值或同一元素上的不同过滤器,您可以将Where子句附加到原始过滤器,并在过滤器本身中使用输入。所以简而言之:完全不清楚为什么你要经历所有这些麻烦,以及为什么你不能在必要时追加Where子句。 – 2009-05-25 16:18:36
@Frans,因为我不能简单地让用户为静态定义的字段指定不同的值。我需要一个完全动态的解决方案来a)减少批量 - 需要维护的一些代码,c)在所有这些下面的类库中提供新类的可扩展性。 – 2009-05-25 18:21:45