我想提供一组过滤器供用户选择,每个过滤器都对应一个Expression<Func<X, bool>>
。所以,我可能想要获取可用项目的动态列表('Joe','Steve','Pete'等),并根据这些名称创建一组“硬编码”过滤器,并让用户选择他想要使用哪个过滤器。我的问题是,即使我尝试根据动态列表中的字符串值“硬编码”我的表达式,表达式仍然将值存储为,看起来是什么,一个悬挂在匿名类型上的属性(和我不知道如何序列化anon。类型)。对不起,如果这令人困惑,我不太清楚如何表达这一点。
这是我的示例代码:
public class Foo
{
public string Name { get; set; }
}
static void Main(string[] args)
{
Foo[] source = new Foo[]
{
new Foo() { Name = "Steven" } ,
new Foo() { Name = "John" } ,
new Foo() { Name = "Pete" },
};
List<Expression<Func<Foo, bool>>> filterLst = new List<Expression<Func<Foo, bool>>>();
foreach (Foo f in source)
{
Expression<Func<Foo, bool>> exp = x => x.Name == f.Name;
filterLst.Add(exp);
}
}
}
我的问题是,当我看到表情的正文时,它的内容如下:
(x.Name = value(ConsoleApplication1.Program+<>c__DisplayClass3).value)
当我真正想要的是第一个阅读时:
(x.Name = "Steven")
(如果我将我的代码改为此代替,那就是我得到的:
Expression<Func<Foo, bool>> exp = x => x.Name == "Steven";
)
我已经尝试将我的值强制转换为本地字符串值,然后将其粘贴到Expression中,但它似乎没有帮助:
List<Expression<Func<Foo, bool>>> filterLst = new List<Expression<Func<Foo, bool>>>();
foreach (Foo f in source)
{
string value = f.Name;
Expression<Func<Foo, bool>> exp = x => x.Name == value;
filterLst.Add(exp);
}
我不明白为什么(或者甚至是如何)它仍在查看某些匿名类型,即使我使用的是声明为字符串的局部变量。有没有办法按照我的意愿来完成这项工作?
答案 0 :(得分:7)
anon-type实际上是用于执行变量 capture 的编译器生成类型。使用委托,您可以通过手动实现捕获来解决这个问题,但不能将lambda表达式编译为表达式树。
两种选择:
后者实际上并不太糟糕;它们通常只是MemberExpression,虽然我有一些代码在全面详细介绍。我还可以提供构建表达式树的示例,但我现在不在PC上,它不适合iPod打字......
从简要读到的问题,我会看第一个选项而不是第二个选项。
哦,小心;问题中的第一个 foreach代码看起来容易受到臭名昭着的l值捕获问题的影响;)
编辑:我找到了一台电脑; p
var param = Expression.Parameter(typeof(Foo), "x");
var body = Expression.Equal(
Expression.PropertyOrField(param, "Name"),
Expression.Constant(f.Name, typeof(string)));
var exp = Expression.Lambda<Func<Foo, bool>>(body, param);
filterLst.Add(exp);
答案 1 :(得分:4)
Marc Gravell的回答是正确的,以下是你如何实现他的第一选择:
var filters =
from f in source
let param = Expression.Parameter(typeof(Foo),"x")
select Expression.Lambda<Func<Foo, bool>>(
Expression.Equal(
Expression.Property(param, "Name"),
Expression.Constant(f.Name)), param);
但这通常不是必需的。你的第二个for循环示例应该适用于所有主要的LINQ提供程序。你需要表达式来使用常量吗?