组合表达式
本文关键字:表达式 组合 | 更新日期: 2023-09-27 18:25:07
我是使用表达式的新手,在我正在处理的一个示例中遇到了一些问题。
我试图实现的是创建一个包含2个(或多个)表达式的表达式。
例如:
public static Expression<Func<Occurrence, bool>> ReporterStartsWithAndClosed()
{
ParameterExpression occPar = Expression.Parameter(typeof(Occurrence));
MemberExpression recorderProp = Expression.Property(occPar, "Reporter");
MemberExpression fullnameProp = Expression.Property(recorderProp, "FullName");
ConstantExpression letter = Expression.Constant("A", typeof(string));
MethodInfo miStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
MethodCallExpression mCall = Expression.Call(fullnameProp, miStartsWith, letter);
MemberExpression oiProp = Expression.Property(occPar, "OccurrenceIncident");
MemberExpression statusProp = Expression.Property(oiProp, "OccurreceIncidentStatus");
MemberExpression nameProp = Expression.Property(statusProp, "Name");
ConstantExpression name = Expression.Constant("Closed", typeof(string));
BinaryExpression equalTo = Expression.Equal(name, nameProp);
return ...?
}
我的问题是,如何将这些表达式组合起来,以返回该方法的正确类型。即,将mCall和equalTo表达式的逻辑组合在一起的语法是什么。
我最初的想法是应该使用BlockExpressions,但我无法实现。
如有任何帮助,我们将不胜感激。
谢谢David
因此,要进行逻辑AND运算,请使用AndAlso()
方法生成表达式。然后,为了完成您的方法,您需要将这个组合方法放入lambda表达式中。
只是一些提示,我会避免在声明中写出类型,这会使所有内容都更难阅读。此外,您可以通过使用Call()
的此重载按名称调用方法,因此无需获取该方法的MethodInfo
对象。
我会这样把它放在一起(未经测试):
public static Expression<Func<Occurrence, bool>> ReporterStartsWithAndClosed(
string letter = "A")
{
// occurrence =>
// occurrence.Reporter.FullName.StartsWith("A")
//
// occurrence.OccurrenceIncident.OccurrenceIncidentStatus.Name == "Closed"
var occurrence = Expression.Parameter(typeof(Occurrence), "occurrence");
var reporter = Expression.Property(occurrence, "Reporter");
var fullName = Expression.Property(reporter, "FullName");
var startsWithLetter = Expression.Call(
fullName,
"StartsWith",
null,
Expression.Constant(letter, typeof(string))
);
var incident = Expression.Property(occurrence, "OccurrenceIncident");
var status = Expression.Property(incident, "OccurrenceIncidentStatus");
var name = Expression.Property(status, "Name");
var equalsClosed = Expression.Equal(
name,
Expression.Constant("Closed", typeof(string))
);
var body = Expression.AndAlso(startsWithLetter, equalsClosed);
return Expression.Lambda<Func<Occurrence, bool>>(body, occurrence);
}