代码之家  ›  专栏  ›  技术社区  ›  DannykPowell

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

  •  4
  • DannykPowell  · 技术社区  · 15 年前

    我的班级定义如下:

    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>
    

    在下一层,我有业务对象,它们将存储库对象作为私有变量保存。

    这很好;

    private ConcreteRepo _repository;
    

    但是,我随后将其重构为所有业务对象的父类-此父类保存存储库/实现释放模式以释放存储库等。

    我的问题是,我只是不能得到正确的语法来声明变量。

    我来的最近的是;

    protected Repository<Object, DataContext> _repository;
    

    但这会导致编译错误:

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

    我试过其他的方法,但遇到了其他问题。

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

    (Repository<LSTableClass, LSDataContext>)_repository = new ConcreteRepo();
    
    • 如果我能在家长那里得到这个声明的话,我想这会很好的。

    如果我不能让它工作,我必须在每个业务对象中声明_存储库,并提供完整/具体的类型详细信息,并在每个对象中实现释放模式以进行清除。不是世界末日,但我不想这样。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Barry Kelly    15 年前

    如果我正确理解了您的问题,您需要添加第三个泛型参数,即存储库类型,它被约束为 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中称为类型类):一种指示类型参数本身是泛型的,并且可以接受类型参数的方法。

        2
  •  3
  •   Matt Brunell    15 年前

    你的声明

    protected Repository<Object, DataContext> _repository;
    

    由于您对其施加的限制,无法工作:

    ...    
    where TDataContext : DataContext, new()
    

    特别是 new() 部分。

    我猜你想“注入”一个满足通用接口的对象。

    两件事:

    • 不能在两者之间转换 Repository<Object, DataContext> Repository<LSTableClass, LSDataContext> . 不适用于C 3。这被称为反方差/协方差,直到C 4才可用。在C 3中,这是两种完全不同的类型。

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

    选项:

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