隐式转换en C#泛型类 [英] Implicit conversion en C# generic classes
问题描述
我有一个应用程序被构建为一个服务层,它使用一个存储库层来实现持久性。
我想创建一个泛型控制器类来重用共享行为,但我在尝试设置泛型参数时遇到了问题。以下代码:
public class BusinessEntity
。不存在从
{}
public class Person:BusinessEntity
{}
public interface IRepository< T> T:BusinessEntity
{}
public interface IService< T,R>
其中T:BusinessEntity
其中R:IRepository< T>
{}
公共部分接口IPersonRepository:IRepository< Person>
{}
公共接口IPersonService:IService< Person,IPersonRepository>
{}
公共抽象类BaseController< X,Y>
其中X:BusinessEntity
其中Y:IService< X,IRepository< X>>
{}
public class PersonController:BaseController< Person,IPersonService>
$ b $ p
$ b在编译时失败
类型
ConsoleApplication.IPersonService
不能在泛型类型或方法中使用类型参数Y
C $ C> ConsoleApplication.BaseController< X,Y>ConsoleApplication.IPersonService
到ConsoleApplication.IService< ConsoleApplication.Person,ConsoleApplication.IRepository< ConsoleApplication.Person>>< code>
此作品
public interface IPersonService: IService< Person,IRepository< Person>>
但我失去了定制存储库
有一种方法可以让编译器实现
IPersonRepository
是IRepository< Person>
?解决方案
public class BusinessEntity
{}
public class Person:BusinessEntity
{}
public interface IRepository< T> T:BusinessEntity
{}
public interface IService< T,R>
其中T:BusinessEntity
其中R:IRepository< T>
{}
公共部分接口IPersonRepository:IRepository< Person>
{}
公共接口IPersonService:IService< Person,IPersonRepository>
{}
公共抽象类BaseController< X,Y,Z>
其中X:BusinessEntity
其中Y:IService< X,Z>
其中Z:IRepository< X>
{}
public class PersonController:BaseController< Person,IPersonService,IPersonRepository>
{}
解决您的评论:
IPersonService可以扩展基本服务类以添加自定义设施,例如FindPersonsUnderAge()。为此,它需要一个自定义存储库。实际上,LINQ避免了大量的自定义存储库代码,但有时它们是必需的。
无需IPersonService而不需要存储库类型是一个类型参数?例如:
public interface IService< T>其中T:BusinessEntity {}
公共接口IPersonService:IService< Person>
{
IEnumerable< Person> FindPersonsByAge(double minAge,double maxAge);
}
公共类服务< T,R> :IService< T>
其中T:BusinessEntity
其中R:IRepository< T>
{}
public class PersonService:Service< Person,IPersonRepository> ;, IPersonService
{}
I have an application that is structured as an service layer wich uses a repository layer for persistence. I'm trying to create a generic controller class to reuse shared behavior but I'm having trouble trying to set the generic parameters. The following code:
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> { }
fails at compilation with
The type
ConsoleApplication.IPersonService
cannot be used as type parameterY
in the generic type or methodConsoleApplication.BaseController<X,Y>
. There is no implicit reference conversion fromConsoleApplication.IPersonService
toConsoleApplication.IService<ConsoleApplication.Person,ConsoleApplication.IRepository<ConsoleApplication.Person>>
this works
public interface IPersonService : IService<Person, IRepository<Person>>
but I lose the custom repository
There is a way to make the compiler realize
IPersonRepository
is anIRepository<Person>
?解决方案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, Z> where X : BusinessEntity where Y : IService<X, Z> where Z : IRepository<X> { } public class PersonController : BaseController<Person, IPersonService, IPersonRepository> { }
To address your comment:
IPersonService can extend the base service class to add custom facilities, like FindPersonsUnderAge(). For this it requires a custom repository. Actually LINQ avoids a lot of custom repository code, but sometimes they are required.
Couldn't IPersonService do that without requiring the repository type to be a type parameter? For example:
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 { }
这篇关于隐式转换en C#泛型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!