我在基类中有一个WhereFilter属性,如下所示:
public virtual Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
get { return null; }
}
Run Code Online (Sandbox Code Playgroud)
当它被覆盖时我想返回别的东西而不是null,所以我可以使用谓词构建器扩展和(来自LinqKit)所以我可以编写我的代码如下:
public override Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
get { return base.WhereFilter.And(x => x.CustomerID == 1); }
}
Run Code Online (Sandbox Code Playgroud)
但是这会产生错误,因为WhereFilter为null(对象引用未设置为对象的实例).
目前我写的是:
public override Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
get { return x => x.CustomerID == 1; }
}
Run Code Online (Sandbox Code Playgroud)
因此,当有另一个子类覆盖它时,基类属性将丢失.
有什么办法解决这个问题?在sql我做的是使用一个假人,其中1 = 1 thingy,这可以在linq中这样做吗?
das*_*ght 17
LINQ相当于SQL的1=1"thingy"是一个始终返回true的谓词:
x => true
Run Code Online (Sandbox Code Playgroud)
更改默认方法如下:
public virtual Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
get { return x=>true; }
}
Run Code Online (Sandbox Code Playgroud)
您可以简单地检查继承的属性是否返回null:
public override Expression<Func<CustomerCustomerType, bool>> WhereFilter
{
get {
var baseResult = base.WhereFilter;
if (baseResult == null) {
return x => x.CustomerID == 1;
} else {
return base.WhereFilter.And(x => x.CustomerID == 1);
}
}
}
Run Code Online (Sandbox Code Playgroud)
IMO这将比看似毫无意义的虚拟值更具可读性,这些虚拟值将使您(或其他任何使用该代码的人)在以后想知道那是什么.(它甚至可能在运行时产生更少的开销.)
如果您坚持使用较少的行,则可以使用运算符缩短if- else表达式?:.
编辑:进一步考虑这一点,你可以看到它是一个缺点,每个覆盖该属性将必须编写这么多代码,这可能会引入错误.但是,在调用继承的代码时,依赖于不包含任何此类错误的重写方法是一个值得怀疑的设计选择,就像您提出的模型一样,覆盖器也可能只返回它们的新谓词而不调用And.
一个更干净的设计,IMO,将创建虚拟属性protected,并让它只返回新的谓词(或null).然后,公共可访问(和非虚拟)属性将负责检索当前和任何超类的任何谓词,并And在有多个超类的情况下将它们组合在一起.