WEB开发网
开发学院软件开发C语言 趣味编程:C#中Specification模式的实现(参考答案... 阅读

趣味编程:C#中Specification模式的实现(参考答案 - 下)

 2010-09-30 21:01:37 来源:WEB开发网   
核心提示: ExpressionVisitor几乎是处理表达式树这种数据结构的不二法门,它可以用于求值,趣味编程:C#中Specification模式的实现(参考答案 - 下)(3),变形(其实是生成新的结构,因为表达式树是immutable的数据结构)等各种操作,ParameterReplacer类的作用

ExpressionVisitor几乎是处理表达式树这种数据结构的不二法门,它可以用于求值,变形(其实是生成新的结构,因为表达式树是immutable的数据结构)等各种操作。例如,解决表达式树的缓存时用它来求树的散列值或读写前缀树,快速计算表达式时用它来提取表达式树的参数,并将不同的表达式树“标准化”为相同的结构。

ExpressionVisitor基类的关键,就在于提供了遍历表达式树的标准方式,如果您直接继承这个类并调用Visit方法,那么最终返回的结果便是传入的Expression参数本身。但是,如果您覆盖的任意一个方法,返回了与传入时不同的对象,那么最终的结果就会是一个新的 Expression对象。ExpressionVisitor类中的每个方法都负责一类表达式,也都都遵循了类似的原则:它们会递归地调用Visit方法,如果Visit返回新对象,那么它们也会构造新对象并返回。

ParameterReplacer类的作用是将一个表达式树里的所有ParameterExpression替换成我们指定的新对象,因此只需覆盖VisitParameter方法就可以了。有了它之后,And和Or方法的实现轻而易举:

public static Expression<Func<T, bool>> And<T>( 
  this Expression<Func<T, bool>> one, Expression<Func<T, bool>> another) 
{ 
  var candidateExpr = Expression.Parameter(typeof(T), "candidate"); 
  var parameterReplacer = new ParameterReplacer(candidateExpr); 
 
  var left = parameterReplacer.Replace(one.Body); 
  var right = parameterReplacer.Replace(another.Body); 
  var body = Expression.And(left, right); 
 
  return Expression.Lambda<Func<T, bool>>(body, candidateExpr); 
} 
 
public static Expression<Func<T, bool>> Or<T>( 
  this Expression<Func<T, bool>> one, Expression<Func<T, bool>> another) 
{ 
  var candidateExpr = Expression.Parameter(typeof(T), "candidate"); 
  var parameterReplacer = new ParameterReplacer(candidateExpr); 
 
  var left = parameterReplacer.Replace(one.Body); 
  var right = parameterReplacer.Replace(another.Body); 
  var body = Expression.Or(left, right); 
 
  return Expression.Lambda<Func<T, bool>>(body, candidateExpr); 
} 

上一页  1 2 3 4  下一页

Tags:趣味 编程 Specification

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接