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

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

posted on 2011-03-26 17:04  Edward.Zhan  阅读(2069)  评论(2编辑  收藏  举报