dans Visual Studio 2008 à l'aide de C #, quelle est la meilleure façon de partager le code sur plusieurs classes et fichiers source? p>
L'héritage n'est pas la solution car les classes ont déjà une hiérarchie significative. p>
Y a-t-il une fonctionnalité NEAT qui ressemble à un fichier C include qui vous permet de déterminer du code partout où vous voulez dans une autre classe? p>
EDIT: P>
OK, je suppose que nous avons besoin d'un exemple concret ... p>
Il y a plusieurs centaines de cours dans le domaine avec une héritière de classe bien pensée. Maintenant, beaucoup de ces classes doivent imprimer. Il existe une classe d'imprimante utilitaire qui gère l'impression. Disons qu'il existe 3 méthodes d'impression différentes qui dépendent de la classe imprimée. Le code qui appelle la méthode d'impression (6 lignes) est ce que j'essaie d'éviter de copier et de coller dans toutes les pages de classe client. p>
Ce serait bien si les gens ne supposaient pas qu'ils connaissaient plus le domaine que l'OP - surtout quand ils mentionnent spécifiquement des techniques qui ne correspondent pas ... p>
10 Réponses :
Une classe d'utilitaire C # fonctionnera. Il agit comme un registre central pour le code commun (ou comme la construction du module VB.net) - il devrait contenir du code qui n'est pas spécifique à une classe sinon il aurait dû être joint à la classe concernée.
vous ne voulez pas strong> vouloir commencer à copier le code source, si vous n'êtes pas obligé, car cela conduirait à des problèmes de mise à jour du code en tenant compte de la double duplication forte>. p> Tant que la source n'a pas besoin de conserver l'état, utilisez une classe statique avec une méthode statique. P> static public class MySharedMembers {
static public string ConvertToInvariantCase(string str) {
//...logic
}
// .... other members
}
Cela crée une dépendance difficile, est difficile à moquer de tester et de violer le principe de responsabilité unique.
Je ne suggère pas beaucoup différemment de (par exemple la classe de regex de Microsoft) qui ne peut être sans doute rien d'autre qu'une dépendance difficile et viole le principe de responsabilité unique. L'auteur n'a pas précisé ce qui doit être réutilisé afin que cette suggestion soit aussi valide qu'une autre. Certainement avec les mandats et les fragments, nous n'avons pas besoin d'être aveuglés par des modèles ou de spéculer sur l'expertise.
Pour être honnête, je ne peux penser à rien de ce genre d'informations inclus dans Visual C #, ni pourquoi vous voudriez que cette fonctionnalité. Cela dit, des classes partielles peuvent faire quelque chose comme ça sonne ce que vous voulez, mais les utiliser peut-être des affrontements contre vos "classes ayant déjà une hiérarchie significative" exigence. P>
Disons que j'ai une méthode d'impression A et la méthode d'impression B. Sur certaines pages, je veux une méthode d'impression A sur d'autres pages que je veux une méthode d'impression B. Il est utile que les méthodes soient statiques car la méthode dépend du code dans la objet. En ce moment, je devais copier collez la méthode correcte sur les pages appropriées ... Il doit y avoir une meilleure façon.
@ mson - Investissez plus de temps dans votre hiérarchie. On dirait que ce dont vous avez besoin est de retravailler votre structure d'héritage afin que les objets utilisables sont dérivés d'un élément commun et il en va de même pour les objets qui utilisent des imprimés
@MSON Il semble que vous souhaitiez peut-être une classe d'imprimante, qui a à la fois des méthodes, que vous pouvez appeler au besoin.
Désolé, mais je ne vois toujours pas pourquoi vous ne pouviez pas implémenter à la fois en imprimante () et à imprimé () comme méthodes de certaines catégories de services publics, puis appelez la méthode correcte de différentes pages, le cas échéant?
Si les classes sont dans la même espace de noms, il n'est pas nécessaire d'inclure un analogique. Appelez simplement les membres de la classe définis dans l'autre fonction. P>
S'ils ne sont pas dans la même espace de noms, ajoutez l'espace de noms des classes que vous souhaitez utiliser dans les directives de jugement et doit fonctionner comme ci-dessus. P>
Je suis confus par la question: il semble que vous ayez besoin de travailler sur votre bonne compréhension de OO. P>
Commander des méthodes d'extension: http://msdn.microsoft.com/fr -us / bibliothèque / bb383977.aspx p>
Je ne suis pas sûr de ce que vous entendez déjà par une structure "significative" déjà, mais cela ressemble à un endroit où vous pourriez utiliser la mise en œuvre de la classe de base. Bien que non aussi «verbose» que le héritage multiple C ++, vous pourriez obtenir des avantages à l'aide de la mise en œuvre de la classe de base chaînée pour réutiliser les fonctions communes. P>
Vous pouvez préserver la hiérarchie de la classe, au moins visuellement et remplacer le comportement au besoin. P>
Quelle classe de base utiliseriez-vous lorsque vos cours sont facturés, employé, enregistrement, patient, voiture, bureau, salle et 300 autres classes?
Les classes de base ne doivent pas nécessairement être une "personneBase", etc. Ils peuvent être "persistablesbase", etc. En C ++, nous aurions un certain nombre de prototypes de classe que nous importerions et rassemblent ensemble, en C #, nous devons le faire à travers une lignée unique. Héritage et interfaces (pour PURE OOP). La langue nous permet également d'utiliser des classes partielles, des méthodes d'extension (ci-dessus 2.0), etc. Cela dépend vraiment de votre graphique d'objet. Y a-t-il une raison pour laquelle vous ne pouvez pas recomposer les objets à utiliser les autres techniques mentionnées?
Vous ne pouvez pas simplement charger du code que vous souhaitez ajouter dans une classe en C # via une directive de pré-déprocession que vous le feriez dans C.
Vous pouvez définir une interface et déclarer des méthodes d'extension pour cette interface. L'interface pourrait ensuite être mise en œuvre par vos classes et vous pouvez appeler les méthodes d'extension sur ces classes. EG P>
public interface IShareFunctionality { } public static class Extensions { public static bool DoSomething(this IShareFunctionality input) { return input == null; } } public class MyClass : Object, IShareFunctionality { public void SomeMethod() { if(this.DoSomething()) throw new Exception("Impossible!"); } }
Brillant! J'ai deux classes, une fonctionnalité très similaire, mais différentes classes de base. Méthodes partagées J'ai pris en compte les méthodes de vulgarisation que vous avez suggérées.
Vous avez de nombreuses options, TT, Extension, Déléguat et Lambda P>
Pouvez-vous expliquer comment le faire avec des délégués ou des lambdas
Lisez à propos de Linq, il utilise une méthode d'extension de lot, déléguée et Lambda pour réutiliser le code, sans une classe «parent / abstrait»
Je ne connais pas un moyen d'inclure des portions de fichiers, mais une chose que nous faisons fréquemment consiste à ajouter un fichier existant et "lien" de son emplacement actuel. Par exemple, nous avons un fichier associéInfo.cs que chaque projet fait référence à partir d'un répertoire de solution. Nous le changeons une fois et tous les projets ont les mêmes informations car ils se réfèrent au même fichier. P>
Sinon, des suggestions sur le refactoring des routines "communes" dans un commun.dll sont la meilleure chose que j'ai proposée dans .net. p>
Si vous avez des fonctionnalités que vous utilisez fréquemment dans des classes qui représentent des choses très différentes, dans mon expérience qui devrait tomber dans quelques catégories:
Pour les fonctionnalités de type utilitaire, vous devez envisager de créer des classes séparées et référencer les classes utilitaires si nécessaire dans la classe d'entreprise. P>
// Simplified example to explain: public interface IPrint { public void Print(string); } public class PrintA : IPrint { public void Print(string input) { ... format as desired for A ... } } public class PrintB : IPrint { public void Print(string input) { ... format as desired for B ... } } class MyPage { IPrint printer; public class MyPage(bool usePrintA) { if (usePrintA) printer = new PrintA(); else printer = new PrintB(); } public PrintThePage() { printer.Print(thePageText); } }
+1 pour AOP / IOC. Cadre d'extensibilité géré (MEF) est un très bon choix car il fera partie du cadre .NET 4.0. mef.codeplex.com ayende.com/blog/archive/2008/09/25/...
+1 C'est aussi comment je voudrais le mettre en œuvre. Si l'héritage ne correspond pas, le prochain choix serait d'examiner l'agrégation.
@Diadistis: Avez-vous utilisé MEF / avez-vous une opinion? J'ai récemment travaillé dans l'environnement Java / Spring et je n'ai pas eu la chance d'essayer du MEF.
Sortez le code répétitif dans les services. Le code répétitif est un indice qu'il pourrait y avoir une place pour le refactoring. P>
Par exemple, créez un "PrintOnService" qui contient la logique nécessaire pour imprimer. Vous pouvez ensuite avoir les classes qui doivent imprimer avoir une dépendance à ce service (via le constructeur ou un paramètre dans une méthode qui nécessite le service). P>
Un autre conseil que j'ai le long de ces lignes est de créer des interfaces pour la fonctionnalité de base, puis d'utiliser les interfaces pour le code. Par exemple, j'ai eu des saisies de classes de rapport que l'utilisateur pourrait soit fax, email ou imprimer. Au lieu de créer des méthodes pour chacun, j'ai créé un service pour chacun, les avions implémenter une interface comportant une seule méthode de sortie (). Je pourrais ensuite passer chaque service à la même méthode en fonction du type de sortie souhaité par l'utilisateur. Lorsque le client souhaitait utiliser EFAX au lieu de faxer par le modem, il s'agissait simplement d'écrire un nouveau service mis en œuvre cette même interface. P>
Le message indique qu'il existe déjà une classe d'imprimante utilitaire ... Le code utilisé pour appeler la méthode est répété dans toutes les classes clientes - c'est ce que je veux ne pas copier et coller. BTW - Le code client appelant a l'objet de regarder lui-même et de déterminer la demande à l'utilitaire d'impression en fonction de l'état de l'objet et des informations d'identification. Votre suggestion est rudimentaire et indicative que vous n'aviez pas lu le poste.
Eh bien, j'ai toujours apprécié la lecture juste pour la valeur éducative
Donc, vous cherchez essentiellement des mélanges en C #?
Pourriez-vous nous montrer les 6 lignes que vous souhaitez dupliquer?
Je ne suis pas sûr de ce qu'est un mélange est
Un mélange est un ensemble de méthodes qui peuvent être «mélangées» dans une autre classe sans que l'autre classe doive dériver d'une classe avec les méthodes. Je pense que le plus proche que vous puissiez entrer dans c # sont des méthodes d'extension. Jetez un coup d'œil à ceux-ci!
Merci DTB - Ce sont les plus proches de ce que je cherchais. Le problème est que la méthode d'appelage examine certaines valeurs d'objet internes avant d'appeler, mais je pourrai peut-être contourner cela. S'il vous plaît poster une réponse pour que je puisse le marquer.
Il y a déjà quelques réponses mentionnant des méthodes d'extension (il n'y a pas de mix-ins en C #). Mais les méthodes d'extension ne peuvent accéder à des membres publics d'une classe élargie. Publiez quelques exemples de vos méthodes d'appel afin que nous puissions voir comment travailler autour de ce problème de manière propre.