![](/img/trans.png)
[英]How to define a generic abstract class that inherits a generic abstract class?
[英]How to point to generic abstract class?
自從我上一個關於接口協方差的問題以來,我就沒有代碼問題。 今天,我對OLGAtherer架構采用了另一種方法,發現了巨大的障礙(對我而言)。 我希望它只對我有用,我會在這里找到答案:)好的,請檢查一下:
我有抽象的泛型類:
abstract class Repository<T> where T : Entity
此類包含四個CRUD方法(添加,插入等)和兩個受保護字段的簽名。 我將創建的任何存儲庫都必須繼承此超類。 我有類似的存儲庫:
class BookRepository : Repository<Book>
現在,我有了負責對DB文件進行操作的類DB。 還有我的問題。 查看放置在DB類中的此方法:
void Add(List<Entity> enitites, Type entityType)
{
Repository<entityType> repo = EntitiesFactory(entityType);
repo.Add(entities);
}
我知道上面的方法不起作用,但是(希望)可以直觀地看到我的問題-我想動態創建指定類型的存儲庫,但是我不知道該怎么做。 這一直是我的主要OOP問題-我可以編碼繼承(或接口的實現),但不能使用這些繼承的類。 請向我澄清一下。 先感謝您。
Paweł
我使用了您提供的提示,這就是我現在所擁有的:
public void Add<T>(List<T> entities, string repoName) where T : Entity
{
Repository<T> repo = RepoFactory<T>(repoName, typeof(T));
repo.Add(entities);
}
private Repository<T> RepoFactory<T>(string repoName, Type t) where T : Entity
{
if (t == typeof(Book))
{
Repository<T> repo = (Repository<T>)((object)(new BookRepository(this.ConnectionString, repoName)));
}
return null;
}
RepoFactory現在在DB類中(順便說一下,這里是某種Bridge)-可能應該將其移到其他地方,但這不是主要問題。
首先,我不知道RepoFactory主體是否以正確的方式實現-我想不是。
其次-我假設我將從其他類中調用數據庫方法(為簡單起見,假設為WindowsForm)。 我將根據用戶的選擇使用參數T調用Add。 這是我遇到的問題,需要臨時解決,因為現在DB可以了,但是如果我必須實現WindowsForm代碼,我會再遇到一次(我認為)-將來我將嘗試找出答案。同樣的問題,但在更高級別(數據庫之上)-我希望您理解我...我的基本意思是,我不知道如何動態調用Add方法,因為T將取決於用戶的選擇(OLGAtherer必須是將支持“書籍”和其他類型收藏的“存儲庫管理器”。 如果用戶嘗試使用他的藏書,則必須調用Add()方法。 如果帶有Comics集合,則添加()。 我不想為每種類型的集合編寫上面的類,而是使用一個Add調用來做到這一點。
如果您理解我的意思,那么您真的很好:)我的英語很爛,但是我正在努力。 感謝您之前的回答,並預先感謝您進一步的回答。 Paweł
我不太確定你想要什么。 這樣可以嗎?
void Add<T>(List<T> entities) where T : Entity
{
Repository<T> repo = EntitiesFactory(typeof(T));
repo.Add(entities);
}
另外,我建議您在輸入參數方面盡可能地靈活,例如,對於此方法以及在Repository<T>.Add()
方法中,請使用IEnumerable<T>
代替List<T>
。 您可能想要傳遞惰性計算的查詢,或將多個LINQ方法鏈接在一起。
您可以使Add
方法通用。
void Add<T>(List<T> enitites)
{
Repository<T> repo = EntitiesFactory(typeof(T));
repo.Add(entities);
}
您可以按如下所示通過一層間接層來修改對象層次結構,從而使其具有類型安全性:
public abstract class EntityCollection<T> : List<T>
where T : Entity
{
public abstract Repository<T> GetRepository();
}
public class BookCollection : EntityCollection<Book>
{
public override Repository<Book> GetRepository()
{
return BookRepository();
}
}
因此,現在您可以按以下方式修改數據庫類:
public void Add<T>(EntityCollection<T> entities)
{
Repository<T> repo = entities.GetRepository();
repo.Add(entities);
}
因此,現在您可以將BookCollection
的實例BookCollection
到您的Add
方法中,它將以100%類型安全,透明的方式工作。
只是為了增加其他所有人的答案,您可能還想看看控制反轉(IoC)設計模式。 它可以簡化您將來的工作。
例如,借助IoC為您提供的依賴項注入,您可以大大簡化EntitiesFactory的使用。
我目前正在使用StructureMap來實現IoC,它對我來說運作良好。
這是有關IoC的Martin Fowler和Wikipedia 的頁面,以幫助您入門。
您在EntitiesFactory()
中返回的內容都是您需要使用的。 因此,問題實際上出在您未顯示的代碼上。 顯示EntitiesFactory()
的代碼,我們會更好地了解您要完成的工作。
注意:您了解,您不能重載返回類型(不幸的是)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.