2009-03-19 8 views
0

Dans le cas où vous avez une fonction qui fonctionne pour beaucoup de différents types personnalisés avec la même mise en œuvre, est-il correct d'utiliser un modèle de conception comme celui-ci ?:Méthode unique pour plusieurs types?

type1 implicitly casts to type0 
type2 implicitly casts to type0 
type3 implicitly casts to type0 

Operate (type0) 

et appelez:

type1 a 
type2 b 
type3 c 

Operate (a) 
Operate (b) 
Operate (c) 

Y a-t-il des problèmes avec cette technique? Performance sage, clarté, etc?

EDIT: Également par moulage implicite, je voulais dire moulages personnalisés pour le type sans perte de données, juste commodité. Supposons que vous ayez une classe Pixel, puis en envoyant une instance de cette méthode à une méthode qui prend un point2, le pixel est automatiquement envoyé à un point2.

Répondre

2

Ceci est une pratique parfaitement normale.

Performance sage, je ne crois pas qu'il y ait des problèmes.

Clarté sage, à cause d'Intellisense, vous avez peu de chances d'avoir des problèmes avec ça non plus.

+0

Intellisense ne vous aidera pas ici. Lorsque vous tapez la méthode Operate(), Intellisense vous indiquera seulement qu'il prend un type0. Vous ne serez pas en mesure de dire que vous pourriez mettre dans un type1 sauf si vous ouvrez la définition de type1. – foson

+0

En fait, il suffit d'appuyer sur les touches haut et bas pour faire défiler les surcharges une fois Intellisense vous montre la méthode. –

+0

Clairement cela ne fonctionne que pour Visual Studio 2005 et supérieur, pour tout autre IDE et votre point peut être correct. –

2

coulée crée généralement un nouvel objet, qui est inutile dans ce cas

Plus façon POO de le faire serait par une classe de base ou d'une interface.

class Type1 : IOperatableType {} 
class Type2 : IOperatableType {} 
class Type3 : IOperatableType {} 

void Operate (IOperatableType a) 

ou

class Type1 : Type0 {} 
class Type2 : Type0 {} 
class Type3 : Type0 {} 

void Operate (Type0 a) 

La méthode appelante (fonctionner dans ce cas) dépend de l'utilisation des méthodes ou des propriétés de ses paramètres. Si ces propriétés/méthodes sont définies sur tous les types (type1, type2, type3), pensez à utiliser une interface qui définit une fonctionnalité commune. Si l'implémentation des propriétés et méthodes est la même, sauvegardez-vous du code répété et pensez à hériter d'une classe de base. En outre, lorsque vous essayez de comprendre votre code, les développeurs sont plus susceptibles de regarder d'abord un diagramme de classes, ce qui leur permet de voir la relation entre les classes, ou au moins la définition de classe (qui montrera les types de base et interfaces) plutôt que d'examiner les opérateurs (implicites/explicites) pour voir quelle classe est transposable à quelle autre classe.

+0

Dépend de la relation entre les objets. Si type2 est un cas particulier de type1, alors le polymorphisme est le chemin à parcourir. – dub

+0

Merci, quel est l'avantage de ceci par rapport à la technique ci-dessus? La raison pour laquelle je me demande est la méthode DoSomething est exactement la même pour tous les types, sauf la conversion qui doit être faite en premier. –

+0

Merci, oui le casting crée de nouveaux objets mais dans le cas de la classe say Pixel, si vous avez des propriétés X et Y, en passant à une méthode qui nécessite Point2, vous aurez toujours besoin de créer ces valeurs dans la méthode, sinon implicitement jeter. –

3

C'est la base du fonctionnement des interfaces.

public interface IBlah { 
    void DoSomething(); 
} 
public class Type1 : IBlah { 
    void DoSomething() { /* implementation */ } 
} 
public class Type2 : IBlah { 
    void DoSomething() { /* implementation */ } 
} 
public class Type3 : IBlah { 
    void DoSomething() { /* implementation */ } 
} 

public class Foo { 
    void Operate(IBlah blah) { 
     blah.DoSomething(); 
    } 
} 
+0

Merci, quel est l'avantage de ceci par rapport à la technique ci-dessus?La raison pour laquelle je me demande est la méthode DoSomething est exactement la même pour tous les types, sauf la conversion qui doit être faite en premier. –

+0

Si vous devez ajouter un nouveau type, même s'il n'est pas lié, il fonctionnera toujours. Par exemple, si les types 1-3 sont des types de voitures, le type 4 est une personne, et DoSomething() est vraiment MoveForward(), tant que l'objet remplit le contrat de l'interface, cela fonctionnera. –

+0

Bon point, merci Chris. –

Questions connexes