2010-05-25 6 views
14

Après un peu de programmation, une de mes classes utilisait des génériques d'une manière que je n'avais jamais vue auparavant. J'aimerais avoir des opinions à ce sujet, si c'est un mauvais code ou non.Utilisation bizarre de génériques

abstract class Base<T> : where T : Base<T> 
{ 
    // omitted methods and properties. 
    virtual void CopyTo(T instance) { /*code*/ } 
} 

class Derived : Base<Derived> 
{ 
    override void CopyTo(Derived instance) 
    { 
     base.CopyTo(instance); 
     // copy remaining stuff here 
    } 
} 

est-ce une utilisation correcte des génériques ou non? Je pense surtout à la contrainte de "se". J'ai parfois l'impression que les génériques peuvent «exploser» dans d'autres classes où j'utilise la classe de base.

+4

En fait ce n'est pas vraiment rare, je l'ai déjà vu ... –

+0

C'est ce que génèrent les génériques. J'exposerais probablement une interface pour la rendre encore plus abstraite. –

+0

Pourquoi avez-vous besoin que le type T soit une base ? Je n'ai vu aucune raison pour cela dans votre échantillon, en fait je n'arrive pas à comprendre pourquoi vous l'utilisez, est-ce que quelque chose me manque? –

Répondre

9

Oui, c'est raisonnable - j'ai quelque chose de similaire dans mon port de tampons de protocole (sauf plus compliqué, car il y a deux types mutuellement référencés). Vous avez absolument raison à propos des génériques qui finissent parfois par se répandre dans le code-base - ce que vous avez fait ici signifie que les bits de code qui ne s'intéressent qu'à Derived ayant une API appropriée n'ont pas besoin de se soucier des génériques .

Mon conseil est d'essayer de garder les choses simples quand cela est possible, mais dans les cas où une contrainte générique «étrange» décrive vraiment ce que vous voulez, allez-y. Vous devez être conscient que cela ne la force utilisation valable si - vous pouvez facilement avoir:

class Banana : Base<Derived> 

et qui serait valable, si étrange et inattendu probablement aux utilisateurs.

Vous pouvez également envisager de sceller Derived ici - si vous dérivez plus loin, vous risquez encore de vous retrouver avec un comportement étrange (ou au moins une API impair).

+0

Jon, ne Banana: Base échouer? Depuis 'où T: base '? –

+1

@Filip Ekberg, non, cela fonctionne, puisque T = 'Derived', et' Derived' est un 'Base ' –

+0

Ah semblait juste un peu étrange :) –

Questions connexes