如果我有一个采用布尔值的方法:
public void Foo(boolean condition)
并称之为:
Foo("MyField" == "MyValue");
我可以将它组成一个表达式树,以便构建一个查询到一些其他数据源,该数据源将MyField用作一个参数,MyValue和另一个。 我似乎只能将这个条件变成一个计算结果为false的表达式。
更新
var param = Expression.Parameter(typeof(Field), field);
var prop = Expression.PropertyOrField(param, "Name");
ConstantExpression @const = Expression.Constant(value, typeof(string));
var body = Expression.Equal(prop, @const);
var lambda = Expression.Lambda<Func<Field, bool>>(body, param);
其中Field是一个具有两个属性的类,名称和值
答案 0 :(得分:4)
Foo("MyField" == "MyValue")
是一个常量false
(编译器正确)。你有几个选择 - 最简单的当然是做一些事情:
void Foo(Expression<Func<YourType,bool>> predicate) {...}
并致电
Foo(x => x.MyField == "MyValue");
然后这里,没有什么可做的;我们已经有了表达方式。所以我假设你的意思是“MyField”是一个只在运行时知道的字符串,在这种情况下:
void Foo<T>(string fieldName, T value) {
var param = Expression.Parameter(typeof(YourType), "x");
var body = Expression.Equal(
Expression.PropertyOrField(param, fieldName),
Expression.Constant(value, typeof(T))
);
var lambda = Expression.Lambda<Func<YourType, bool>>(body, param);
}
并使用Foo("MyField", "MyValue)
进行调用(由编译器提供隐式<string>
)或Foo("MyField", 123)
如果prop是int
(隐式{{1} }}),
最后一个场景是<int>
也是字符串,仅在运行时已知(emph:"MyValue"
) - 在这种情况下,我们需要解析它:< / p>
string
此处的通话总是2个字符串 - 所以void Foo(string fieldName, string value) {
var param = Expression.Parameter(typeof(YourType), "x");
var prop = Expression.PropertyOrField(param, fieldName);
ConstantExpression @const;
if(prop.Type == typeof(string)) {
@const = Expression.Constant(value, typeof(string));
} else {
object parsed = TypeDescriptor.GetConverter(prop.Type)
.ConvertFromInvariantString(value);
@const = Expression.Constant(parsed, prop.Type);
}
var body = Expression.Equal(prop,@const);
var lambda = Expression.Lambda<Func<YourType, bool>>(body, param);
}
即使Foo("MyField", "123")
。
答案 1 :(得分:1)
In可以从委托创建表达式树。例如,如果您定义方法以便将委托作为参数,则可以按如下方式使用它:
public void Foo(Func<bool> fn)
{
// invoke the passed delegate
var result = fn();
}
Foo(() => "MyField" == "MyValue");
为了创建表达式树而不是执行委托,请按如下方式更改方法:
public void Foo(Expression<Func<bool>> expression)
{
// inspect your expression tree here
}
但是,在你的情况下,你会发现你的表达式是一个值为'false'的布尔常量,这是因为编译器已经评估了"MyField" == "MyValue"
,这当然是假的。
如果您只想要名称 - 值对,而不只是使用Dictionary<string, string>
?