我有一個類/接口層次結構。在接口方面我有流利的接口使用類型推斷
IQuery
ISelect (inherits IQuery)
IUpdate (inherits IQuery)
etc
在課程方面我有
QueryBase (implements IQuery)
SelectQuery (implements ISelect)
UpdateQuery (implements IUpdate)
etc
很明顯,例如,無論是更新和選擇類共享一個WHERE子句,但只有一個選擇具有GROUP BY功能,因此最好如果正在創建更新查詢,則流暢接口將不會授予對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;
}
與朋友分享(內部)方法,SetWhere實現它作爲一個擴展方法,對QueryBase允許我更新的WHERE子句。但是,由於泛型限制爲IQuery,它不會找到SetWhere。但是,如果我將其約束爲QueryBase,那麼顯然,編譯器會拋出異議,說ISelect找不到AddWhere方法。
我在想,我還沒有完全得到我想要實現的繼承鏈或接口實現。
(我希望這是明確的!)
我會很感激,如果有人可以建議要麼我在哪裏的擴展方法實現,或者我應該如何更好地安排我的類/接口方面腳麻層次結構。
我覺得,因爲它討論的是你一個簡單的形式http://stackoverflow.com/questions/1723648/how-to-inherit-method-but-with-different-return-type可能是有用的閱讀正在嘗試。它主要說它不可能,儘管有幾個解決方法,包括使您的基類Generic。我認爲如果你對代碼重組感到滿意,最後一部分(dtb的答案)可能會做你想做的。 – Chris 2012-02-17 11:04:13
克里斯我玩了一下。那個q只和具體的類對話,我想知道我的場景是否也被一個接口層次結構複雜化了。我試圖將QueryBase通用化爲QueryBase(T作爲IQuery),但那意味着,AFAICS,我的例如「SelectQuery工廠」將需要返回SelectQuery或QueryBase(的ISelect)而不是ISelect。同樣,流利的方法也需要返回混凝土。由於ISP /易於嘲弄,我返回純粹的接口。我錯過了什麼嗎? – 2012-02-18 12:49:45
恐怕我不知道。我知道這個問題稍微有點不同,如果它能夠工作,需要做一些調整,但我之前沒有這樣做,也沒有時間自己去玩。可能這些問題不會幫助你完美地解決問題,我只是希望。 ;-) – Chris 2012-02-20 10:16:45