隐式转换en C#泛型类 [英] Implicit conversion en C# generic classes

查看:145
本文介绍了隐式转换en C#泛型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序被构建为一个服务层,它使用一个存储库层来实现持久性。
我想创建一个泛型控制器类来重用共享行为,但我在尝试设置泛型参数时遇到了问题。以下代码:

  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 parameter Y in the generic type or method ConsoleApplication.BaseController<X,Y>. There is no implicit reference conversion from ConsoleApplication.IPersonService to ConsoleApplication.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 an IRepository<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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆