2010-10-05 10 views
0

Imaginez que j'ai une classe de base générique comme ceci:Comment utiliser un niveau de base générique à deux niveaux dans une arborescence d'héritage?

public abstract class AnimalDTO<TA, TB> 
{ 
    public static TB ToDTO(TA entity) 
    { 
     return ConvertToDTO<TB>(entity); 
    } 
} 

La classe est responsable d'être en mesure de convertir une entité passé en un DTO.

J'ai une classe qui utilise cette classe générique:

public class MammalDTO<Mammal, MammalDTO> 
{ 
    // omitted stuff here 
} 

Un utilisateur peut désormais utiliser MammalDTO.ToDTO(mammal) pour convertir un Mammal à un MammalDTO.

Maintenant, je veux tirer au large des mammifères:

public class Koala<???, ???> : Mammal<???, ???> 

Comment puis-je faire?

Répondre

1

Une solution serait de faire MammalDTO un type générique ouvert mais contraint. Vous pouvez ensuite essayer de contraindre le générique de plus en plus au fur et à mesure que vous descendez dans la hiérarchie d'héritage, en le fermant sur une feuille. Il peut également convenir d'utiliser des classes abstraites, mais ce n'est pas une exigence du modèle.

Pour être honnête, cependant, je n'aime pas vraiment le modèle 'autoréférencement générique'; Je trouve cela assez déroutant.

public abstract class Animal { } 
public abstract class Mammal : Animal { } 
public sealed class Koala : Mammal { } 

public abstract class AnimalDTO<TAnimal, TDTO> where TAnimal : Animal 
{ 
    public abstract TDTO ConvertToDTO(TAnimal entity);  
} 

public abstract class MammalDTO<TMammal, TMammalDTO> : AnimalDTO<TMammal, TMammalDTO> 
    where TMammal : Mammal 
    where TMammalDTO : MammalDTO<TMammal, TMammalDTO>{} 

public sealed class KoalaDTO : MammalDTO<Koala, KoalaDTO> 
{ 
    public override KoalaDTO ConvertToDTO(Koala entity) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Merci. Je pense que je vais essayer de trouver une autre façon de le faire, car je n'aime pas ce modèle non plus. –