2010-04-20 13 views
9

Tengo dos tipos abstractos genéricos: Entity y Association.Cómo declarar una restricción genérica que es un tipo genérico

Digamos Entity se parece a esto:

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

y Association se parece a esto:

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

¿Cómo se ve limitada por la Asociación para que puedan ser de cualquier entidad?

puedo lograr que por lo siguiente:

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

Esto se vuelve muy tedioso como más tipos derivan de Association, porque tengo que seguir pasando hasta tres veces al día y TId2. ¿Hay una forma más simple de hacerlo, además de eliminar la restricción?

Respuesta

11

Este problema generalmente se resuelve teniendo su clase genérica (Entity<TId>, en este caso) hereda de una clase no genérica común clase.

public abstract class EntityBase 
{ 

} 

public class Entity<TId> : EntityBase 
{ 

} 

Esto le permite hacer:

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

} 

Editar

Si tenerlos heredan de una clase común es un problema, entonces esto podría hacerse fácilmente con una interfaz como bien.

+0

¡¡Muy bonito !! +1. – Nayan

+0

Sí, ya había llegado a la conclusión de que una interfaz se adecuaría mejor a mis necesidades, ¡excepto que necesito reajustar mis interfaces para tener una base no genérica! Esperaba que hubiera un buen truco de lenguaje, pero por desgracia ... – HackedByChinese

+0

@HackedByChinese: estoy seguro de que es algo que podría agregarse, pero dado que hay una solución existente que es tanto simple como 100% efectiva (sin sacrificar ninguna funcionalidad), es probable que no veamos nada parecido a 'TEntity ' en el corto plazo;) –

0

Si los Id tipos son importantes dentro de la definición Association, se podría crear un "contexto" que encierra:

public static partial class EntityIds<TId1, TId2> { 

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

} 

De esta manera, la declaración de clase Association sigue siendo inteligible, y conserva los argumentos de tipo necesarias para sus parámetros de tipo.

Un método de fábrica que podría ayudar con el caso normal:

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

Es que se parece demasiado, y si usted no tiene especializaciones entidad, se podría modelar la asociación diferente:

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