如何指向通用抽象类?

时间:2010-11-19 19:48:46

标签: c# oop class inheritance generics

自从我上一次使用接口协方差问题以来,我没有遇到代码问题。今天我采用了另一种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问题 - 我可以编写继承(或接口的实现)但我不能使用这些继承的类。请向我澄清一下。提前谢谢。

帕维尔


我使用了你提供的提示,这就是我现在所拥有的:

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的身体是否以正确的方式实施 - 我猜不是。

第二 - 我假设我将从其他类调用DB方法(比方说 - WindowsForm,为简单起见)。我将使用参数T调用Add,具体取决于用户的选择。这是我遇到问题并暂时修复它的情况,因为现在DB正常,但是如果我必须实现WindowsForm代码,我将再次遇到它(我想) - 将来我会试着找出答案同样的问题,但在更高的层面(DB以上) - 我希望你理解我... 我基本上是说,我不知道如何动态调用Add方法,因为T将依赖于用户的选择(OLGAtherer必须是Repository Manager,它将支持Books和其他类型的集合)。如果用户尝试使用他的图书集,我将不得不调用Add()方法。如果使用Comics集合,则添加()。我不想为每种类型的集合编写上面的类,而是使用Add的一个调用来执行此操作。

如果你明白我的意思,你真的很好:)我的英语很糟糕,但我正在努力。 感谢您以前的回答,并提前感谢您的回答。 帕维尔

5 个答案:

答案 0 :(得分:7)

我不太确定你想要什么。这会吗?

void Add<T>(List<T> entities) where T : Entity
{
   Repository<T> repo = EntitiesFactory(typeof(T));
   repo.Add(entities);
}

此外,我建议您尽可能灵活地使用输入参数,例如:对此方法以及IEnumerable<T>方法使用List<T>而不是Repository<T>.Add()。您可能希望传入一个延迟评估的查询,或者将多个LINQ方法链接在一起。

答案 1 :(得分:3)

您可以将Add方法设为通用。

void Add<T>(List<T> enitites)
{
   Repository<T> repo = EntitiesFactory(typeof(T));
   repo.Add(entities);
}

答案 2 :(得分:2)

您可以通过以下一层间接修改对象层次结构来使其类型安全:

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的实例传递到Add方法中,它将以100%类型安全,透明的方式工作。

答案 3 :(得分:2)

只是为了添加其他人的答案,您可能还想看一下控制反转(IoC)设计模式。它可以简化你未来工作中的生活。

使用依赖注入(IoC为您提供),您可以显着简化EntitiesFactory的使用,例如。

我目前正在使用StructureMap来实施IoC,它对我来说效果很好。

以下是IoC上的Martin Fowler's页面,以及Wikipedia's,以帮助您入门。

答案 4 :(得分:1)

无论你在EntitiesFactory()返回什么,都需要使用。所以问题实际上是你没有展示过的代码。显示EntitiesFactory()的代码,我们会更好地了解您要完成的任务。

注意:您了解不能重载返回类型(不幸的是)。