Как объявить универсальное ограничение, являющееся универсальным типом - PullRequest
9 голосов
/ 20 апреля 2010

У меня есть два общих абстрактных типа: Entity и Association.

Допустим, 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 ]

11 голосов
/ 20 апреля 2010

Эта проблема обычно решается с помощью наследования вашего общего класса (в данном случае Entity<TId>) от общего неуниверсального класса.

public abstract class EntityBase
{

}

public class Entity<TId> : EntityBase
{

}

Это позволит вам сделать:

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

}

Редактировать

Если проблема заключается в том, что их наследование от общего класса является проблемой, то это можно легко сделать и с помощью интерфейса.

0 голосов
/ 30 июня 2010

Если в определении Association важны типы Id, вы можете создать включающий «контекст»:

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