Linq系列(8)——表达式树之应用场景

it2026-01-07  8

    大家好,很久没在这里写博客了。最近情况很糟糕,遭遇失恋的打击,导致本人近来心理上出现了极大的问题,所以一直无心写博。今天提笔前还把之前一篇博文读了一遍。按计划这篇该写应用场景了。

    相信大家通过前面几篇文章的阅读和学习,对表达式树已经有了一定的了解。对于这个系列,我可能只会再写2篇文章。

    大家应该可以理解表达式树由body和parameter是2部分组成,然后,方法能实现的功能表达式树都可以实现。表达式树可以用来表示一个逻辑过程,并且,可以让用户传入parameter.也就是说,表达式树可以使逻辑过程独立。

    所以,在我平时的项目里面,在一个应用场景下,我会首先想到使用表达式树。

    下面,我将为大家解释这个应用场景:

     比如我们有个类:Aircraft ,有一个属性:AirlineId

    

     public   class  Aircraft    {         public   string  AirlineId        {             get ;             set ;        }         public  Aircraft()        {         }         public   bool  Test()        {             return   true ;        }    }

    同时我们还有另外一个类SubFleet,也有一个属性AirlineId

   

public   class  SubFleet    {         public   string  AirlineId        {             get ;             set ;        }         public  SubFleet()        {         }    }

    这2个类没有任何的继承关系,在我们的solution中使用这2个类的实例的时候,都需要判断AirlineId不为null且不为空。这只是一个例子,在实际项目中,我们需要的判断的逻辑可能远比不为null不为空复杂。所以我们希望能写一个通用的方法,能对所有的含有AirlineId这个属性的对象进行判断。

    好了,这个时候,泛型和表达式树就派上用场了,我们可以运用表达式树写出如下方法:

   

public   bool  TestAirlineId < T > (T instance)        {            ParameterExpression aircraftParameter  =  Expression.Parameter( typeof (T),  " testInstance " );            MemberExpression memberAirlineIdExpression  =  Expression.Property(aircraftParameter,  " AirlineId " );            ConstantExpression nullConstant  =  Expression.Constant( null );            ConstantExpression emptyConstant  =  Expression.Constant( string .Empty);            Expression < Func < T,  bool >>  equalNull  =  Expression.Lambda < Func < T,  bool >>                                                                          (Expression.Equal(memberAirlineIdExpression, nullConstant),                                                                           new  ParameterExpression[] { aircraftParameter }                                                                          );            Expression < Func < T,  bool >>  equalEmpty  =  Expression.Lambda < Func < T,  bool >>                                                                           (                                                                            Expression.Equal(memberAirlineIdExpression, emptyConstant),                                                                             new  ParameterExpression[] { aircraftParameter }                                                                          );            Expression < Func < T,  bool >>  expressionString  =  Expression.Lambda < Func < T,  bool >>                                                                            (                                                                             Expression.Or(equalNull.Body, equalEmpty.Body),                                                                              new  ParameterExpression[] { aircraftParameter }                                                                           );            Func < T,  bool >  method  =  equalNull.Compile();             return  method(instance);        }      

    好的,这样一来,所有含有“AirlineId”这个属性的对象都可以用这个方法来判断该属性是否不为空且不为empty。

    但是这么做就有一个问题了,要是传入的对象不含"AirlineId"这个属性怎么办,那不是会遇到运行时的异常,我们是否能在编译时就检查到不含这个属性的错误呢?

    答案是肯定的,只需要传入一个MemberExpression,并且,如果传入的是MemberExpression的话,连泛型也不用了,但这样一来,调用的人就麻烦了。这种例子我在前面的博文中写过大家可以自己权衡。

     好了,今天就写这么多,我再写一篇总结的文章就将结束这个系列,在这个系列结束后,我会写关于silverlight&&Prism的系列。希望大家能留意.

    有任何问题,可通过我邮箱zxhlelva@126.com和QQ:244873327联系。

    我叫Edward。

转载于:https://www.cnblogs.com/FlyEdward/archive/2011/03/26/Linq_ExpressionTree8.html

相关资源:数据结构—成绩单生成器
最新回复(0)