如何声明泛型类型的泛型约束

时间:2010-04-20 18:19:27

标签: c# generics constraints

我有两种通用的抽象类型:EntityAssociation

让我们说Entity看起来像这样:

public class Entity<TId>
{ 
//...
}

Association看起来像这样:

public class Association<TEntity, TEntity2>
{
//...
}

如何约束关联以便它们可以属于任何实体?

我可以通过以下方式完成它:

public class Association<TEntity, TId, TEntity2, TId2>
     where TEntity : Entity<TId>
     where TEntity2: Entity<TId2>
{
//...
}

随着更多类型派生自Association,这变得非常繁琐,因为我必须继续传递TId和TId2。除了删除约束外,还有更简单的方法吗?

2 个答案:

答案 0 :(得分:11)

此问题通常通过让您的泛型类(在本例中为Entity<TId>)继承自公共非泛型类来解决。

public abstract class EntityBase
{

}

public class Entity<TId> : EntityBase
{

}

这样你就可以:

public class Association<TEntity, TEntity2>
    where TEntity : EntityBase
    where TEntity2 : EntityBase
{

}

修改

如果让它们从公共类继承是一个问题,那么这也可以通过接口轻松完成。

答案 1 :(得分:0)

如果Id定义中的Association类型很重要,您可以创建一个封闭的“上下文”:

public static partial class EntityIds<TId1, TId2> {

    public class Association<TEntity1, TEntity2>
      where TEntity1 : Entity<TId1>
      where TEntity2 : Entity<TId2>
    {
      // ...
    }

}

这样,Association类声明仍然可以理解,并且它保留了类型参数的必要类型参数。

工厂方法可以帮助您处理正常情况:

public static class AssociationFactory {
  public static EntityIds<TId1, TId2>.Association<Entity<TId1>, Entity<TId2>> Create<TId1, TId2>(/*params...*/) {
    return new EntityIds<TId1, TId2>.Association<Entity<TId1>, Entity<TId2>>(/*params...*/);
  }
}

看起来太多了,如果你没有实体专业化,你可以用不同的方式对关联进行建模:

public class Association<TId1, TId2>
{
  // ... 
  Entity<TId1> Entity1 { get; set; }
  Entity<TId2> Entity2 { get; set; }
  // ...
}