大家好,很久没在这里写博客了。最近情况很糟糕,遭遇失恋的打击,导致本人近来心理上出现了极大的问题,所以一直无心写博。今天提笔前还把之前一篇博文读了一遍。按计划这篇该写应用场景了。
相信大家通过前面几篇文章的阅读和学习,对表达式树已经有了一定的了解。对于这个系列,我可能只会再写2篇文章。
大家应该可以理解表达式树由body和parameter是2部分组成,然后,方法能实现的功能表达式树都可以实现。表达式树可以用来表示一个逻辑过程,并且,可以让用户传入parameter.也就是说,表达式树可以使逻辑过程独立。
所以,在我平时的项目里面,在一个应用场景下,我会首先想到使用表达式树。
下面,我将为大家解释这个应用场景:
比如我们有个类:Aircraft ,有一个属性:AirlineId
{
public string AirlineId
{
get;
set;
}
public Aircraft()
{
}
public bool Test()
{
return true;
}
}
同时我们还有另外一个类SubFleet,也有一个属性AirlineId
{
public string AirlineId
{
get;
set;
}
public SubFleet()
{
}
}
这2个类没有任何的继承关系,在我们的solution中使用这2个类的实例的时候,都需要判断AirlineId不为null且不为空。这只是一个例子,在实际项目中,我们需要的判断的逻辑可能远比不为null不为空复杂。所以我们希望能写一个通用的方法,能对所有的含有AirlineId这个属性的对象进行判断。
好了,这个时候,泛型和表达式树就派上用场了,我们可以运用表达式树写出如下方法:
{
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。