C# 将具体的类实例强制转换为使用泛型的接口
这是我从抽象基类派生的具体存储库C# 将具体的类实例强制转换为使用泛型的接口,c#,generics,interface,casting,C#,Generics,Interface,Casting,这是我从抽象基类派生的具体存储库 public class DepartmentRepository : RepositoryBase<Department>, IDepartmentRepository public abstract class RepositoryBase<T> : IRepository<T> where T : class, IPersistantBusinessObject 如何将DepartmentRepository转换为通
public class DepartmentRepository : RepositoryBase<Department>, IDepartmentRepository
public abstract class RepositoryBase<T> : IRepository<T> where T : class, IPersistantBusinessObject
如何将DepartmentRepository转换为通用IRepository
DepartmentRepository rep = new DepartmentRepository();
(IRepository<IPersistentBusinessObject>)rep; // this doesn't work
DepartmentRepository=newdepartmentrepository();
(i推定)代表;//这不管用
想法?如果您想知道,这是一个使用存储库模式的asp.net MVC3应用程序。我是否过度设计了接口?我现在应该如何使用通用存储库
谢谢
编辑:
这是我的IRepository界面。当被问及为什么我需要强制转换到IRepository时,实际上只有这样我才能使用“SaveChanges”方法,因为我想截取数据库中的任何异常并以一种常见的方式进行处理
public interface IRepository<T> where T: IPersistantBusinessObject
{
IQueryable<T> Retrieve();
T Retrieve(int id);
IQueryable<T> RetrieveActiveAndInActive();
T RetrieveActiveAndInActive(int id);
void Add(T domainObject);
void SaveChanges();
void Delete(T domainObject);
void Delete(int id)
}
公共接口i位置,其中T:IPersistantBusinessObject
{
IQueryable检索();
T检索(int-id);
IQueryable RetrieveActiveAndInActive();
T RetrieveActiveAndInActive(int id);
void Add(T域对象);
void SaveChanges();
无效删除(T域对象);
无效删除(int-id)
}
您需要将其强制转换为IRepository
DepartmentRepository
源自RepositoryBase
,它实现了IRepository
你可能想看看 你想在这里做什么?我想不出有哪种情况下你会想投到
IRepository
。什么代码依赖于什么抽象
我通常期望其他代码依赖于IDepartmentRepository
的抽象,并且根本看不到IRepository
或IPersistentBusinessObject
的用例。同样,如果您能找到依赖于该抽象的代码用例,那么它们是有价值的;否则
(顺便说一句,这就是测试驱动开发之所以有价值的原因之一。你可以通过编写单元测试,看看需要模拟哪些类来隔离某些功能的测试,而不是因为被告知它们比具体的类型更好,而只是模糊地将所有东西抽象到接口中,从而找出你需要哪些抽象从具体类型开始,当您的测试强制您提取接口时,正是时候!)
真的,这是一个问题,如果你说
public interface IRepository<out T> where T : IPersistantBusinessObject
公共接口i位置,其中T:IPersistantBusinessObject
正如Daniel所暗示的,您不能将其强制转换为IRepository,因为您已将IRepository接口定义为仅与另一个类型t结合存在。因此,作为接口的“IRepository”不存在
如果您希望能够使用接口“IRepository”,那么它需要是没有类型依赖的独立接口
也许您需要两个接口,一个实现IRepository中所需的基本功能,另一个实现T类型的通用方法。
e、 g
公共接口假定
{
SaveChanges()
...
}
其中T:IPersistantBusinessObject的公共接口IRepository
{
T GetFirst();//或其他什么
...
}
什么是“这不起作用”意思?确切的错误消息是什么?回答“我是否过度设计了接口?”:是的。我不确定您从这个奇怪的继承/实现图中获得了什么。另外,如果您已经将它作为部门存储库
,为什么要直接将其转换到此接口?@Jim-我得到了一个InvalidCastException。感谢链接,但我不想将其转换到IRepository…我还需要其他具体的存储库t在“通用”中使用方法…例如,思考产品、顺序、类别等。我必须尝试一下上面的方法,并对所有这些进行更多的思考。我的目标是为我的存储库和业务对象使用接口,我还希望它们具有泛型基类…这意味着我的接口使用泛型。哦,常见用法实际上是在我的单元测试中案例。例如,我在nunit中的存储库:Assert.Throws(rep.Save())…然后是一系列测试。我想将所有这些都打包到一个通用例程中。对我来说,抽象泛型基类作为实现细节是有意义的,但作为契约的泛型接口却没有意义。
public interface IRepository<T> where T: IPersistantBusinessObject
{
IQueryable<T> Retrieve();
T Retrieve(int id);
IQueryable<T> RetrieveActiveAndInActive();
T RetrieveActiveAndInActive(int id);
void Add(T domainObject);
void SaveChanges();
void Delete(T domainObject);
void Delete(int id)
}
public interface IRepository<out T> where T : IPersistantBusinessObject
<!-- language: lang-c# -->
public interface IRepository
{
SaveChanges()
...
}
public interface IRepositoryFor<T> where T : IPersistantBusinessObject
{
T GetFirst(); // or whatever
...
}