简体   繁体   English

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

[英]How to declare a generic constraint that is a generic type

I have a two generic abstract types: Entity and Association . 我有两个通用的抽象类型: EntityAssociation

Let's say Entity looks like this: 让我们说Entity看起来像这样:

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

and Association looks like this: Association看起来像这样:

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

How do I constrain Association so they can be of any Entity? 如何约束关联,以便它们可以属于任何实体?

I can accomplish it by the following: 我可以通过以下方式完成它:

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

This gets very tedious as more types derive from Association , because I have to keep passing down TId and TId2. 随着更多类型派生自Association ,这变得非常繁琐,因为我必须继续传递TId和TId2。 Is there a simpler way to do this, besides just removing the constraint? 除了删除约束之外,还有更简单的方法吗?

This problem is usually solved by having your generic class ( Entity<TId> , in this case) inherit from a common non-generic class. 这个问题通常通过让您的泛型类(在本例中为Entity<TId> )继承自公共非泛型类来解决。

public abstract class EntityBase
{

}

public class Entity<TId> : EntityBase
{

}

This will allow you to do: 这将允许您:

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

}

Edit 编辑

If having them inherit from a common class is an issue, then this could be easily done with an interface as well. 如果让它们从公共类继承是一个问题,那么这也可以通过接口轻松完成。

If the Id types are important inside the Association definition, you could create an enclosing "context": 如果Id类型在Association定义中很重要,您可以创建一个封闭的“context”:

public static partial class EntityIds<TId1, TId2> {

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

}

This way, the Association class declaration is still intelligible, and it retains the necessary type arguments for its type parameters. 这样, Association类声明仍然可以理解,并且它为其类型参数保留必要的类型参数。

A factory method could help you with the normal case: 工厂方法可以帮助您正常情况:

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...*/);
  }
}

It that looks like too much, and if you don't have entity specializations, you could model the association differently: 它看起来太多了,如果你没有实体专业化,你可以用不同的方式建立关联模型:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM