C#泛型类的隐式转换

C#泛型类的隐式转换,c#,generics,C#,Generics,我有一个应用程序,它的结构是服务层,使用存储库层进行持久化。 我试图创建一个通用控制器类来重用共享行为,但在设置通用参数时遇到了问题。以下代码: public class BusinessEntity { } public class Person : BusinessEntity { } public interface IRepository<T> where T : BusinessEntity { } public interface IService<T, R&

我有一个应用程序,它的结构是服务层,使用存储库层进行持久化。 我试图创建一个通用控制器类来重用共享行为,但在设置通用参数时遇到了问题。以下代码:

public class BusinessEntity
{ }

public class Person : BusinessEntity
{ }

public interface IRepository<T> where T : BusinessEntity
{ }

public interface IService<T, R>
    where T : BusinessEntity
    where R : IRepository<T>
{ }

public partial interface IPersonRepository : IRepository<Person>
{ }

public interface IPersonService : IService<Person, IPersonRepository>
{ }

public abstract class BaseController<X, Y>
    where X : BusinessEntity
    where Y : IService<X, IRepository<X>>
{ }

public class PersonController : BaseController<Person, IPersonService>
{ }
但是我丢失了自定义存储库

有一种方法可以使编译器实现
IPersonRepository
是一个
IRepository

公共类业务实体
{ }
公共类人士:商业实体
{ }
公共接口i位置,其中T:BusinessEntity
{ }
公共接口设备
其中T:商业实体
其中R:i假定
{ }
公共部分接口IPersonRepository:IRepository
{ }
公共接口IPersonService:iSeries设备
{ }
公共抽象类BaseController
其中X:业务实体
Y:IService在哪里
其中Z:i假定
{ }
公共类PersonController:BaseController
{ } 
针对您的评论:


IPersonService可以扩展基本服务类以添加自定义工具,如FindPersonUnderage()。为此,它需要一个自定义存储库。实际上,LINQ避免了许多自定义存储库代码,但有时它们是必需的

IPersonService不能在不要求存储库类型为类型参数的情况下执行此操作吗?例如:

public interface IService<T> where T : BusinessEntity { } 

public interface IPersonService : IService<Person>
{
    IEnumerable<Person> FindPersonsByAge(double minAge, double maxAge);
}

public class Service<T, R> : IService<T>
    where T : BusinessEntity 
    where R : IRepository<T> 
{ }

public class PersonService : Service<Person, IPersonRepository>, IPersonService
{ }
公共接口IService,其中T:BusinessEntity{}
公共接口IPersonService:iSeries设备
{
IEnumerable FindPersonsByAge(双minAge,双maxAge);
}
公共课服务:IService
其中T:商业实体
其中R:i假定
{ }
公共类PersonService:服务,IPersonService
{ }

感谢sll为我指明了正确的方向

public interface IService<T, out R>
    where T : BusinessEntity
    where R : IRepository<T>
{ }
公共接口iSeries设备
其中T:商业实体
其中R:i假定
{ }

这是因为默认情况下,X:Person与
IRepository不相同,默认情况下,这类泛型类型没有差异。你使用的是哪个版本的.NET Framework?如果我有这个能力,我会授予你一个“破解编译器”徽章。从我花了整整5分钟的时间试图使它工作起来,我的直觉结论是编译器不够聪明,无法完成您希望它完成的任务。我使用的是.NET4。我没有想到变化,我认为它值得一试。我不完全喜欢UI开发人员必须了解存储库这一事实,但这是一个可以接受的折衷办法。@JamesGordon在这种情况下,我会选择
接口IPersonService:IService
,因此,该服务的消费者不需要知道任何关于该服务如何持久化其数据的信息,甚至不需要知道它依赖于
i存储库。PersonService的哪些方法需要person存储库的类型参数?IPersonService可以扩展基本服务类以添加自定义工具,如FindPersonUnderage()。为此,它需要一个自定义存储库。实际上,LINQ避免了许多自定义存储库代码,但有时它们是必需的。@JamesGordon我的问题归结为“iSeries设备的
R
类型参数在哪里使用?难道就不能是
iSeries设备
?请参阅编辑后的响应以获取草图。使用代码,我现在就可以得到它。是的,这是一种更清洁的解决方案。我认为你的答案是可以接受的。谢谢
public interface IService<T> where T : BusinessEntity { } 

public interface IPersonService : IService<Person>
{
    IEnumerable<Person> FindPersonsByAge(double minAge, double maxAge);
}

public class Service<T, R> : IService<T>
    where T : BusinessEntity 
    where R : IRepository<T> 
{ }

public class PersonService : Service<Person, IPersonRepository>, IPersonService
{ }
public interface IService<T, out R>
    where T : BusinessEntity
    where R : IRepository<T>
{ }