我有一个类/接口层次结构。在接口方面,我有:
IQuery
ISelect (inherits IQuery)
IUpdate (inherits IQuery)
etc
在类的层面上,我有:
QueryBase (implements IQuery)
SelectQuery (implements ISelect)
UpdateQuery (implements IUpdate)
etc
显然,例如,Update和Select类都共享一个WHERE子句,但只有Select具有GROUP BY功能。因此,如果正在创建Update查询,则流畅接口将不提供访问GROUP BY功能,但如果正在创建SelectQuery,则应该提供该功能。
例如,在流畅接口术语中:
var/Dim select = New SelectQuery() <- returns ISelect explicit
.AddColumn(....) <- returns ISelect explicit
.AddWhere(....) <- returns ISelect inferred
.AddGroupBy(....) <- returns ISelect explicit
var/Dim update = New UpdateQuery() <- returns IUpdate explicit
.AddSet(....) <- returns IUpdate explicit
.AddWhere(....) <- returns IUpdate inferred
我不确定如何实现AddWhere函数。
之前我在IQuery接口中声明了AddWhere函数:
Function AddWhere(ByVal condition As ICriterion) As IQuery
IQuery AddWhere(ICriterion condition)
但是因为它返回一个IQuery,我失去了类型推断的好处,所以一旦流畅的接口强制转换为IQuery,如果正在创建一个Select查询,我将不再拥有例如AddGroupBy方法的访问权限。
因此,我尝试使用泛型实现它作为扩展方法。
<Extension>
Public Function AddWhere(Of T As IQuery)(Byval this as T, Byval condition as Condition) as T
this.SetWhere(condition)
Return Me
End Function
public T AddWhere<T>(T @this, Condition condition) where T : IQuery
{
@this.SetWhere(condition);
return this;
}
通过对QueryBase进行内部友元(internal Friend)方法SetWhere的设置,使我能够更新WHERE子句。但是因为泛型受到IQuery的约束,它找不到SetWhere。然而,如果我将其约束为QueryBase,则编译器会抛出异常,说无法找到AddWhere方法。
我认为我还没有完全理解继承链或接口实现,以达到我想要的目标。
如果有人能建议我在扩展方法实现方面出了什么问题,或者如何更好地构建我的类/接口层次结构,我将不胜感激。
(希望我的表述清晰明了!)