簡體   English   中英

如何指向泛型抽象類?

[英]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 FowlerWikipedia 頁面,以幫助您入門。

您在EntitiesFactory()中返回的內容都是您需要使用的。 因此,問題實際上出在您未顯示的代碼上。 顯示EntitiesFactory()的代碼,我們會更好地了解您要完成的工作。

注意:您了解,您不能重載返回類型(不幸的是)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM