我的课程定义如下;
public abstract class Repository<TEntity, TDataContext> : DisposableBaseClass
where TEntity : class
where TDataContext : DataContext, new()
{...contains Linq to SQL related functionality
在具体的子类中,我将类型定义为;
public class ConcreteRepo : Repository<LSTableClass, LSDataContext>
在下一层,我有业务对象,它将Repository对象保存为私有变量。
这很好;
private ConcreteRepo _repository;
然而,我然后将其重构为所有业务对象的父类 - 这个父类保存存储库/实现Dispose模式以处置存储库等。
我的问题是我无法获得声明变量的语法。
我最接近的是;
protected Repository<Object, DataContext> _repository;
但这会产生编译错误:
“错误1'System.Data.Linq.DataContext'必须是具有公共无参数构造函数的非抽象类型,才能在泛型类型或方法中将其用作参数'TDataContext'... .Repository” ...“
我尝试了其他各种方法,但遇到了其他问题。
在继承此抽象类的业务层对象中,我正在创建并使用带有强制转换的_repository变量;
(Repository<LSTableClass, LSDataContext>)_repository = new ConcreteRepo();
如果我无法使用它,我必须使用完整/具体类型的详细信息在每个业务对象中声明_repository,并在每个业务对象中实现dispose模式以清除。不是世界末日,但我不想这样做。
答案 0 :(得分:3)
如果我正确理解您的问题,您需要添加第三个通用参数,即存储库类型,它被约束为具有适当参数类型的Repository
的后代。
再概述一下:
public abstract class Repository<TEntity,TDataContext>
where TEntity : class
where TDataContext : DataContext, new() {}
public abstract class BusinessObject<TEntity,TDataContext,TRepository>
where TEntity : class
where TDataContext : DataContext, new()
where TRepository : Repository<TEntity,TDataContext>
{
TRepository _repository;
}
public class ConcreteObject : BusinessObject<LSTableClass,LSDataContext,ConcreteRepo>
{ // ...
我知道它可能没有你想要的那么紧凑,但是为了有效地减少这个但仍然保留强类型需要的是高阶泛型类型(在Haskell中称为类型类):一种指示类型参数的方法它们本身是通用的,可以采用类型参数。
答案 1 :(得分:3)
您的声明
protected Repository<Object, DataContext> _repository;
由于你对它施加的限制而无效:
...
where TDataContext : DataContext, new()
特别是new()
部分。
我猜你想要“注入”满足你的通用界面的对象。
两件事:
您无法在Repository<Object, DataContext>
和Repository<LSTableClass, LSDataContext>
之间进行转换。不是C#3。这称为反演/协方差,在C#4之前不可用。在C#3中,这两种是完全不同的类型。
如果要将泛型成员存储在类中,则类型参数必须是具体类型,或者必须在父类声明中声明为类型参数(使 < / strong>通用)。
选项: