2009-05-04 126 views
4

我有一个类定义如下;用于声明抽象泛型类型变量的C#语法

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<LSTableClass, LSDataContext>)_repository = new ConcreteRepo(); 
  • ,我认为这将是罚款,假设我可以用鼠标右键在父获得此声明。

如果我不能得到这个工作,我必须在每个业务对象中声明_repository,具有完整/具体类型的详细信息,并在每个业务对象中实现dispose模式以清除。不是世界末日,但我不想。

+0

所以我正确理解“私人ConcreteRepo _repository;”在你重构的类中?你想让你写的类包含这个存储库字段* AND *是Repository的TEntity类型参数?确切地说,你重构的东西对我来说不是很清楚。 – 2009-05-04 22:17:54

回答

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中称为类型类):一种指示类型参数本身是泛型的方法,并且可以采用类型参数。

+0

谢谢巴里,这正是我所需要的,现在所有的工作,非常感谢 – DannykPowell 2009-05-05 06:28:41

3

你的宣言

protected Repository<Object, DataContext> _repository; 

难道不是因为你赋予它约束的工作:

...  
where TDataContext : DataContext, new() 

具体的new()部分。

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

两件事情:

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

  • 如果你想一个普通的会员店一类的里面,那么该类型的参数或者必须是具体的类型,或者他们必须声明为在父类声明的类型参数(使通用)。

选项:

  • 使用你的父类的泛型类型参数。
  • 从您的类声明中删除new()约束。
+0

感谢您的答案马特;不幸的是,我似乎只能将一个答案标记为正确的答案,否则我也会标记你的答案。当你把它们放到第一个选项时,我猜你是正确的,因为你需要注入一个对象,所以需要保留new()约束。再次感谢您的答复 – DannykPowell 2009-05-05 06:33:02