![](/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.