我有一个类/interface层次结构。在界面方面,我有
IQuery
ISelect (inherits IQuery)
IUpdate (inherits IQuery)
etc在课堂上,我有
QueryBase (implements IQuery)
SelectQuery (implements ISelect)
UpdateQuery (implements IUpdate)
etc显然,例如,更新和选择类都共享一个WHERE子句,但只有选择类具有GROUP BY功能,因此理想情况下,如果正在创建更新查询,fluent接口将不会提供对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,所以我失去了类型推断的好处,所以一旦fluent接口转换为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上使用一个朋友(内部)方法SetWhere,允许我更新WHERE子句。但是,因为泛型被限制为IQuery,所以它找不到SetWhere。但是,如果我约束为QueryBase,那么很明显,编译器会抛出错误,说明ISelect找不到AddWhere方法。
我在想,对于我试图实现的目标,我还没有完全掌握继承链或接口实现。
(我希望这是清楚的!)
如果有人能建议我在扩展方法实现方面出错的地方,或者我应该如何更好地构造我的类/接口层次结构,我将不胜感激。
发布于 2012-02-17 17:43:39
也许你可以在你的层次结构中使用另一个接口,比如:
interface IQuery
interface IConditional : IQuery
interface ISelect : IConditional
interface IUpdate : IConditional然后,IConditional接口可以直接在接口定义中使用AddWhere方法,也可以将其作为约束在IConditional类型上的扩展方法。
https://stackoverflow.com/questions/9325795
复制相似问题