繁体   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