2010-04-20 75 views
9

我有两个通用的抽象类型: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。有没有更简单的方法来做到这一点,除了删除约束?

回答

11

这个问题通常通过让您的泛型类(Entity<TId>,在这种情况下)从通用的类继承而来,即非类属的类。

public abstract class EntityBase 
{ 

} 

public class Entity<TId> : EntityBase 
{ 

} 

这将允许你这样做:

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

} 

编辑

如果让他们从一个共同的类继承的是一个问题,那么这可以很容易地与界面完成好。

+0

非常好! +1。 – Nayan 2010-04-20 18:36:55

+0

是的,我已经得出结论,一个界面最适合我的需求,除非我需要重新调整我的界面以获得非通用基础!我希望有一个整洁的语言技巧,但可惜... – HackedByChinese 2010-04-20 18:47:03

+0

@HackedByChinese:我敢肯定这是可以添加的东西,但考虑到现有的解决方法既简单又100%有效(不牺牲任何功能),我们很可能不会在短时间内看到类似'TEntity '的任何东西;) – 2010-04-20 18:49:16

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