我正在尝试创建一个通用任务层(在我的项目中称为AppServ)以与我的Generic Repository交互。这是我第一次涉及泛型,并且遇到了将值传递给泛型类中的泛型方法参数的问题:
Base App Services类(由特定的app servc类继承并调用Generic Repository):
public class BaseAppServ<T> : IBaseAppServ<T> where T : class, IEntity, IAuditStamps, ICompanyFacility, new()
{
private Repository<T> _repository;
private T _viewModel;
private AuditStampsViewModel _auditStamps;
public BaseAppServ(Repository<T> repository)
{
_repository = repository;
_viewModel = new T();
_auditStamps = new AuditStampsViewModel();
}
这是我的特定AppServ类(继承BaseAppServ)
public class ManageItemsAppServ : BaseAppServ<ManageItemsAppServ>, IEntity, IAuditStamps, ICompanyFacility
{
public ManageItemsAppServ()
: base(CallBaseConstructor())
{
}
public static Repository<Item> CallBaseConstructor()
{
return new Repository<Item>(new InventoryMgmtContext());
}
我在构造函数或ManageItemsAppServ中遇到问题,特别是在基础(CallBaseConstructor())行中。它给出了错误:
Argument 1: cannot convert from 'OTIS.Data.Repository<OTIS.domain.InventoryMgmt.Item>' to 'OTIS.Data.Repository<OTIS.AppServ.InventoryMgmt.ManageItemsAppServ>'
我想我知道为什么会发生这种情况(因为当我继承BaseAppServ时,我指定了类型为ManageItemsAppServ的T并且为整个BaseAppServ类设置了T的类型......对吗?)
那么如何重新定义T以寻找类型Respository?
的构造函数调用编辑: 所以我想我需要在BaseAppServ类中添加第二个泛型参数(注意我约束的U类型存储库):
public class BaseAppServ<T, U> where U : Repository<U>, IBaseAppServ<T> where T : class, IEntity, IAuditStamps, ICompanyFacility, new()
{
private Repository<U> _repository;
private T _viewModel;
private AuditStampsViewModel _auditStamps;
public BaseAppServ(Repository<U> repository)
{
_repository = repository;
_viewModel = new T();
_auditStamps = new AuditStampsViewModel();
}
这似乎是正确的道路,现在唯一的错误是:
Inconsistent accessibility: constraint type 'OTIS.AppServ.IBaseAppServ<T>' is less accessible than 'OTIS.AppServ.BaseAppServ<T,U>'
这与BaseAppServ类声明的顺序/语法有关。它应该是什么?
答案 0 :(得分:1)
您尝试将Repository<Item>
作为构造函数参数传递,其中Repository<ManageItemsAppServ>
是预期的。
请注意,即使Item
继承自ManageItemsAppServ
,这也不是有效的操作,因为泛型类不能是共变或逆变。
因此,简而言之,请确保传递确切类型,或使用协变的接口(接口是否可以协变取决于其上的方法)。
修改强>
根据你的编辑,你可能想要这样的东西:
public class BaseAppServ<TModel, TItem>: IBaseAppServ<TModel>
where TItem : class, IEntity
where TModel: ICompanyFacility, new()
{
private Repository<TItem> _repository;
private TModel _viewModel;
private AuditStampsViewModel _auditStamps;
public BaseAppServ(Repository<TItem> repository)
{
_repository = repository;
_viewModel = new TModel();
_auditStamps = new AuditStampsViewModel();
}