通用应用约束时出错

时间:2014-05-31 19:33:46

标签: c# generics

我有这些模特课:

public abstract class ModelBase<T>
{
   public virtual T Id { get; set; }
}

public class Table: ModelBase<int>
{
   public string Name { get; set; }
}

我的问题是当我需要使用我的存储库时,我需要类型为Table并放置类型参数或约束:

public class Repository<TEntity> 
         : IRepository<TEntity> where TEntity 
         : ModelBase<T> //I know there's a mistake, but as it is needed

我如何能够推断Table中的int类型是TEntity还是对它的引用?

在这种情况下,

Table为{{1}}

3 个答案:

答案 0 :(得分:4)

你非常接近。要在示例中使用T,您需要提供该类型。为了提供类型,需要将它传递给类构造函数,因此它需要在定义中。您可以像这样包含它

public class Repository<TEntity,T> 
                              //^ Include the type in the definition
     : IRepository<TEntity> where TEntity 
     : ModelBase<T>

现在当你实例化时,你需要传递表格和表格类型

var repo = new Repository<Table,int>();

答案 1 :(得分:1)

我相信,您不会拥有任何重要数量的主键变体。所以,你可以轻松地做到这一点:

public class TableWithIntId : ModelBase<int>
{
}

public class TableWithGuidId : ModelBase<Guid>
{
}

public class Repository<TEntity, T> : IRepository<TEntity> 
    where TEntity : ModelBase<T>
{
}

public class TableWithIntIdRepository<TTable> : Repository<TTable, int>
    where TTable : TableWithIntId
{
}

public class TableWithGuidIdRepository<TTable> : Repository<TTable, Guid>
    where TTable : TableWithGuidId
{
}

当你需要每个Repository的{​​{1}}后代,而不是每个实体都需要T后代时,这会让你陷入困境。

答案 2 :(得分:0)

我发现这个解决方案很容易实现。我创建了一个类ModelBaseIdentity<T>来解决我的问题:

public abstract class ModelBase
{
   // code
}

public abstract class ModelBaseIdentity<T>: ModelBase
{
   public virtual T Id { get; set; }
}

public class Table: ModelBaseIdentity<int>
{
   public string Name { get; set; }
}


public class Repository<TEntity> 
         : IRepository<TEntity> where TEntity 
         : ModelBase