C#用于声明抽象泛型类型变量的语法

C#用于声明抽象泛型类型变量的语法,c#,generics,abstract-class,C#,Generics,Abstract Class,我有一个定义如下的类 public abstract class Repository<TEntity, TDataContext> : DisposableBaseClass where TEntity : class where TDataContext : DataContext, new() {...contains Linq to SQL related functionality 然而,我随后将其重构为所有业务对象的父类-该父类包含repository/im

我有一个定义如下的类

public abstract class Repository<TEntity, TDataContext> : DisposableBaseClass
   where TEntity : class
   where TDataContext : DataContext, new()
{...contains Linq to SQL related functionality
然而,我随后将其重构为所有业务对象的父类-该父类包含repository/implements Dispose模式以处置repository等

我的问题是,我只是无法获得变量声明的正确语法

最近的一次是

protected Repository<Object, DataContext> _repository;
protectedrepository\u Repository;
但这会导致编译错误:

“错误1”System.Data.Linq.DataContext“必须是具有公共无参数构造函数的非抽象类型,才能将其用作泛型类型或方法“…存储库”…”中的参数“TDataContext”。

我尝试过其他各种方法,但遇到了其他问题

在继承这个抽象类的业务层对象中,我创建并使用带有cast的_repository变量

(Repository<LSTableClass, LSDataContext>)_repository = new ConcreteRepo();
(Repository)\u Repository=new ConcreteRepo();
  • 我认为这会很好,假设我能在家长的报告中得到正确的声明

如果我无法实现这一点,我必须在每个业务对象中声明_存储库,以及完整/具体的类型详细信息,并在每个对象中实现dispose模式以进行清理。不是世界末日,但我不想非得这么做。

如果我正确理解了您的问题,您需要添加第三个通用参数,即repository type,它被约束为具有适当参数类型的
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>
{ // ...
公共抽象类存储库
地点:班级
其中TDataContext:DataContext,new(){}
公共抽象类BusinessObject
地点:班级
其中TDataContext:DataContext,new()
存放地点:存储库
{
存储库;
}
公共类ConcreteObject:BusinessObject
{ // ...
我知道它可能不像您希望的那样紧凑,但要有效地减少这种情况,同时仍然保留强类型,需要的是高阶泛型类型(在Haskell中称为类型类):一种表示类型参数本身是泛型的方法,可以接受类型参数。

您的声明

protected Repository<Object, DataContext> _repository;
特别是
new()
部分

我猜您希望“注入”一个满足通用接口的对象

两件事:

  • 您不能在
    存储库
    存储库
    之间进行转换。不能使用C#3。这称为逆变/协方差,在C#4之前不可用。在C#3中,这是两种完全不同的类型

  • 如果要在类内存储泛型成员,则类型参数必须是具体类型,或者必须在父类声明中声明为类型参数(使成为泛型)

选项:

  • 在父类上使用泛型类型参数
  • 从类声明中删除new()约束

我是否正确理解了“私有混凝土回购库”是否在您重构的类中?您希望您正在编写的类包含此repository字段并成为repository的TEntity类型参数?您重构的确切内容对我来说不是很清楚。谢谢Barry,这正是我需要的,现在都在工作,非常感谢Matt的回答;不幸的是,我似乎只能标记o如果答案是正确的,否则我也会把你的标记为正确答案。我使用了第一个选项,因为你的猜测是正确的,我需要注入一个对象,所以需要保留new()约束。再次感谢你的答案
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>
{ // ...
protected Repository<Object, DataContext> _repository;
...    
where TDataContext : DataContext, new()