2010-10-06 126 views
10

我试图在编写我的应用程序时遇到的相当大(对我而言)的问题。 请看看这个(我会尽量缩短代码的简单性):C中的接口继承#

我有根接口叫IRepository<T>。 接下来,IBookRepository : IRepository<Book> 接下来,具体的类实现它:BookRepository : IBookRepository

在RepositoryManager I类声明private IRepository<IRepoItem> currentRepo;

IRepoItem是由图书类实现的接口。

现在,当我尝试做这样的事情:

currentRepo = new BookRepository(); 

VisualStudio中给出的错误信息:

无法隐式转换类型 'BookRepository' 到 'IRepository'。一个显式转换存在(是否缺少强制转换?)

我想明确地投,但运行时抛出异常......

我知道(几乎是肯定的),这是一种叫做协方差这可能(可能)在.Net 4.0中解决。 不幸的是,我正在使用框架版本3.5,我不能改变这一点。请给我一些建议做什么 - 如何超越这个问题?我想从RepoFactory获取currentRepo,这会根据用户需求生成几种类型的存储库。我不知道链接是否被允许在这里,但我写了一些博客http://olgatherer.wordpress.com/,我描述了应用程序创建。我的英语不好,但我希望能够理解我。预先感谢您的回答。

最好的问候, skrzeczowas

+0

什么是currentRepo声明的类型? – 2010-10-06 13:35:11

+0

没关系,我看到它是一个IRepository 。 – 2010-10-06 13:38:17

回答

4

在.NET 3.5的你绝对不能把一个IRepository<Book>IRepository<IRepoItem>

我们需要了解更多关于你在RepositoryManager中使用存储库的内容,才能真正知道如何解决它......但是,您可以创建IRepository<T>延伸的非通用IRepository接口吗?使其包括所有不参考T的成员。然后,您可以声明currentRepo仅作为IRepository

+0

+1 - 我想过这个非泛型的'IRepository'接口,但不知道如何实现它。优秀的乔恩! =) – 2010-10-06 13:40:56

+0

再次嗨!我以这里描述的方式创建了存储库:http://olgatherer.wordpress.com/2010/08/18/repositoriesrus/我创建了DbManager来管理数据库并为每个表(书籍,漫画,后期邮票等)创建存储库)。现在我想DbManager中的currentRepository可能是BookRepository,StampsRepository,不管 - 我认为这个接口的东西可以,但不幸的是,因为IRepoItem(就像我现在意识到的)应该有所有不同的属性,然后... :( – skrzeczowas 2010-10-07 06:33:44

0

在.NET 3.5中没有.NET 4 IRepository和IRepository之间的任何关系,你可以做到这样的事情与协变和逆变支持(但它取决于IRepository接口声明)

A将推荐使用非通用的IRepository接口并自己进行转换。我知道,这并不好,但你描述的功能需要协变/逆变支持。

+0

谢谢你这个答案,我用下面这一个,并意识到,这并不完全适合我:(我不知道该怎么做现在... IRepoItem不能拥有所有的书籍,漫画,邮票大小为:( – skrzeczowas 2010-10-07 06:35:31

1

尝试使用中间层(IRep):

interface IRepository<T> 
    { 
    } 

    interface IRep<T> : IRepository<IRepoItem> where T : IRepoItem 
    { 
    } 

    interface IBookRepository : IRep<Book> 
    { 
    } 

    class BookRepository : IBookRepository 
    { 
    } 

那么你可以做你想做的:

 BookRepository br = new BookRepository(); 
     IRepository<IRepoItem> currentRepo = br; 
+0

嗨!这是非常棒的,非常高雅,我非常高兴你发布了这个。不幸的是,正如我在上面发表的评论中所描述的,我意识到这并不完全适合我.IRepoItem是一个可以在书籍,邮票,漫画中实现的界面,这样它就可以拥有不同项目的所有属性,这并不聪明,我必须找到另一种方法来实现我想要的 - 这意味着我希望currentRepo是BookRepository或StampsRepository或任何其他仓库...也许一些帮助,请吗? – skrzeczowas 2010-10-07 06:38:44

+0

IRepoItem作为其他东西的接口应该只会导致它巩固它们共同的东西,而不是“所有属性”。例如,IMoveable应该只显示Move方法,并不是所有类派生的东西(如Cheetah,Car,Airplane)都有。 – Grozz 2010-10-07 06:45:52

+0

但是,如果我说,将有currentRepo = StampsRepo(),我将只能使用IRepository组成的方法。我将无法使用IStampsRepository方法:(我相信我可以再问一下这个currentRepo是什么类型的:if(currentRepo是IBookRepository)如果(currentRepo是IStampsRepository)做一些其他的事情......但这不是好的对象编程,我认为,我必须重新考虑我所做的所有假设,因为也许我想要的是愚蠢的并且不可实现...... – skrzeczowas 2010-10-07 07:10:06