[英]Casting, Generics, and Subtypes
在嘗試實現存儲庫模式時,我遇到了一個小問題,我擔心其實會掩蓋更大的問題。
我有一個DatabaseEntity <T>
,我用它來處理所有基本的CRUD操作,並且需要存儲在數據庫中的所有其他類都將從中運行。 它適用於直接從它繼承的類,但是當它與具有中間父類的類一起使用時,我遇到了問題。
假設我有三個其他類,Parent,ChildA和ChildB,並且繼承看起來像:
DatabaseEntity
|
親
| |
ChildA ChildB
還假設DatabaseEntity <T>
具有帶以下簽名的方法:
public static T FindBy(int id)
我遇到的問題是當我嘗試這樣的事情時:
ChildA Foo = ChildA.FindBy(SomeID);
我收到編譯器錯誤,告訴我沒有從Parent到ChildA的隱式轉換。 這是因為Parent是將ChildA和ChildB的類型參數傳遞給DatabaseEntity的類。 我認為簡單的修復,只需向Parent添加一個類型參數,從而通過適當的類型。 只需等待一秒鍾,然后我必須在使用Parent時明確定義子類型,這會破壞任何多態性。 不,第二個想法也許這不是一個很好的修復。
我認為我可以在類DatabaseEntity本身上刪除類型參數,並讓每個方法都需要一個類型參數但是我必須做類似的事情:
ChildA Foo = ChildA.FindBy<ChildA>(SomeID);
雖然編譯,但它似乎不太干凈,當然需要更多打字。 Visual Studio詢問我是否錯過了一個演員,而真正的我可以在我意外輸出之前將我的第一個例子投射到它只是時間問題:
ChildB Foo = (ChildB) ChildA.FindBy(SomeID)
我對目前為止我想到的任何解決方案都不是特別滿意,我希望有人可以指出一個我錯過的優雅解決方案。
我認為讓Parent
成為一個通用類是Parent
的方法。 您沒有解釋示例中T
類型的確切目的,但我想您希望它是實體的實際類型,例如,您的Parent
將繼承Entity<Parent>
。
您仍然可以在此場景中編寫多態代碼 - 您只需使用泛型:
static void Foo<T>(Parent<T> p) where T : Parent<T>
{
Parent<T> entity = p.Find();
}
這種方法可以既被稱為ChildA
和ChildB
。 唯一棘手的方面是你實際上不能創建Parent<Parent<...>>
的實例(因為點必須用更多嵌套的Parent<...>
類型替換),但你可以寫這樣的東西:
class ParentFix : Parent<ParentFix> { }
..然后你也可以將ParentFix
實例ParentFix
給Foo
方法。
我知道這不是你正在尋找的答案,但我建議使用一個堅固的現成ORM,如Entity Framework 4.它支持開箱即用的繼承,它的基本用途是基礎知識庫。
如果你試圖自己動手,我覺得你很痛苦。
對不起,如果我不從這里獲得更大的畫面,但你可以
DatabaseEntity<T>
一個單獨的通用類(靜態的而定),而不會導出
Parent
從它。
這種安排將允許使用
DatabaseEntity<T>
定義的所有CRUD操作與您可能擁有的任何類。
PS:如果我錯過了一些明顯的東西,請不要激怒我,我寧願做一些澄清,這樣我才能學得更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.