8
votes

Les méthodes d'extension et ses implications dans l'ingénierie logicielle (ou constituent-t-elle vraiment une bonne idée?)

À droite, SE MS présente Méthodes d'extension pour C # 3.0 . Fondamentalement, cela vous permet d'ajouter de nouvelles méthodes à une classe existante sans avoir à la sous-classement ni à modifier sa mise en œuvre. Les cloches d'alarme immédiatement vont dans mon esprit.

1) Vous commencez à implémenter vos propres méthodes d'extension pour une bibliothèque ou des classes de bibliothèque standard. Maintenant, il n'est plus standardisé.

2) Dans OOP, vous définissez un nouveau type par héritage ou composition. Qu'est-ce qui est réellement des méthodes d'extension alors? De même, en utilisant des méthodes d'extension, aucune relation explicite n'est définie.

3) Les méthodes d'extension sont-elles portables entre les projets? Et si deux méthodes d'extension pour une méthode existe?

Les méthodes d'extension sont-elles un tas de vers qui méritent d'éviter? Je peux voir qu'il y en a des mérites, comme dans vous, de type, mais il semble que cela ressemble à une mauvaise pratique.

opinions?


3 commentaires

Environ 200 000 de la réputation donnant leurs opinions en 7 minutes ... pas mauvais!


Voir aussi Stackoverflow. com / questions / 487904 / ... et Stackoverflow.com/ Questions / 403539 / What-Are-Extension-méthode s


... environ la moitié d'où est Jon.


7 Réponses :


9
votes

Méthodes d'extension ne sont pas ajoutés à un type. Ils ne sont que du sucre syntaxique. Vous ne pouvez pas accéder à des trucs privés. Une méthode d'extension est comme n'importe quelle méthode statique qui consomme un type.

La pire chose à faire est de faire du mal à lisciplier et de tromper les gens. Au-delà de la syntaxe, ils sont inexistants.

Mise à jour (Re commentaire):

C'est exactement ce que je voulais dire de "personnes trompeuses" et "nuire à la lisibilité". Heureusement, Visual Studio est très utile pour distinguer des méthodes d'extension (à l'aide d'une icône dans la liste IntelliSense et de l'info-bulle). Personnellement, je suis un peu biaisé contre l'ajout d'un tas de méthodes de vulgarisation pour classes arbitraires du cadre (à l'exception des classes scellés lorsque les méthodes d'extension peuvent faire beaucoup de Sens) Sauf si ils fournissent un avantage significatif pour le projet particulier. Je préfère garder les méthodes d'extension principalement pour les interfaces et les classes sur les niveaux supérieurs de hiérarchie d'héritage. Cela fera que les développeurs ne les utilisent que là où ils sont applicables à de nombreux cas dans le cadre plutôt que de faire une méthode d'utilité une extension (OMI, il s'agit d'un artefact direct d'autodécouverte de méthodes d'extension dans un espace de noms entiers. Je souhaite vraiment que c # a obligé que cm # ait obligé d'ajouter A en utilisant la directive sur la classe spécifique plutôt que d'importer automatiquement toutes les extensions dans un espace de noms ).

Dans mon expérience, si vous n'utilisez pas les méthodes d'extension en faisant toutes les méthodes utilitaires utilisées plusieurs fois (j'ai vu certaines personnes le faire) une extension, c'est rarement un problème de maintenance. Il améliorera la lisibilité s'il est utilisé à bon escient.

Encluencer les cours avec des méthodes de vulgarisation n'est pas une bonne chose. Dans les cas extrêmes, cela peut être dangereux. On peut introduire une collision de noms en ajoutant une méthode en classe avec le même nom d'une extension déjà existante. Cela peut casser des extraits de code qui ont déjà appelé l'extension et appelent maintenant la nouvelle méthode.
À mon avis, il s'agit du problème le plus important associé aux méthodes de vulgarisation. Cela rend une bonne nommaison d'extensions très importantes.


1 commentaires

Merci pour l'explication. Je souhaite juste demander, dans votre expérience, comment les méthodes d'extension impact sur le partage du code ou la remise des projets à une nouvelle équipe. Dis que j'ajoute un "WordCount ()" à String - est-il apparent qui est une méthode d'extension et non une méthode de chaîne réelle? Comment cela fonctionne-t-il pour le maintien du code?



5
votes

Non, ce n'est pas une boîte de vers qui mérite d'éviter. Il peut rendre la vie beaucoup plus simple et il vous permet de séparer les opérations principales du type des méthodes "Helper" qui peuvent être implémentées uniquement à partir de ces opérations principales. J'ai été tenté d'utiliser des méthodes d'extension de cette façon même quand elles ne sont pas vraiment nécessaires (c'est-à-dire que j'ai eu une classe de base pour les mettre dans, et je contrôle le code du code. ).

Vous devez comprendre que les méthodes d'extension sont juste un moyen de faire des appels de méthode statiques ressemblent à des méthodes d'instance, lorsque l'espace de noms approprié contenant les méthodes d'extension est importé. En particulier:

  • IT ne doit pas Ajoutez des méthodes à un type, il ne s'agit donc pas de bibliothèques standard "non standard". Cela signifie simplement que si vous avez les méthodes d'extension disponibles, vous pourrez peut-être travailler avec ces bibliothèques plus facilement.
  • est une relation explicite définie avec des méthodes d'extension: la méthode d'extension déclare quel type il est "s'étendant" avec le type du premier paramètre. Ce n'est pas la composition ou l'agrégation, mais je ne vois pas pourquoi c'est un problème. Si quelque chose est utile et ne fait pas réellement que le design pire, il est important de savoir s'il fait partie de OO traditionnel?
  • Oui, les méthodes d'extension sont portables entre les projets. Comme toujours, il existe des règles pour ce qui se passe si deux méthodes d'extension avec le même nom sont visibles en même temps.

    Les méthodes d'extension sur les interfaces sont très Nice, permettant une chaîne de méthode simple, etc. Je voudrais bien voir une méthode d'extension qu'un appel statique explicite comme dans Java: xxx

    quelques inconvénients cependant:

    • Cela ne permet pas aux types dérivés de remplacer la mise en œuvre de manière plus efficace. Bien sûr, le type dérivé peut déclarer une méthode avec la même signature, mais cela ne vous utilisera que si le type de temps de compilation est approprié.
    • La manière dont les méthodes d'extension sont découvertes dans C # est une douleur. J'ai remporté ça ailleurs ...
    • Les méthodes d'extension ne sont pas disponibles lors de l'utilisation de dactylographie dynamique.

      Globalement, je pense qu'ils sont charmants - et lorsqu'ils sont utilisés avec modération, ils peuvent faire toute la différence. Je ne voudrais certainement pas utiliser Linq sans eux.


4 commentaires

Jon, où puis-je trouver votre déclaration sur la découverte de la méthode d'extension?


Va voir si je peux le creuser. Il y a quelques informations ici: MSMVPS.com/blogs/jon_skeet/archive/2008/02/10/... - Mais je vais voir si j'en ai plus.


Un très vieux message ici: MSMVPS.com/blogs/jon_skeet/ Archives / 2005/09/28/68147.aspx Fondamentalement, le problème est que c'est très large - vous obtenez tout à partir d'un espace de noms entier, même si vous ne voulez qu'un seul type. Cela signifie que si vous souhaitez créer différentes méthodes d'extension à différents types, vous devez envisager de les diviser dans différents espaces de noms juste pour donner plus de contrôle à l'utilisateur . Cela conduit à beaucoup plus d'espaces de noms que vous ne voudrez normalement, souvent avec un ou deux types de personnes.


Merci John, très apprécié :)



5
votes

Les méthodes d'extension ne modifient pas du tout la classe existante, elles ne sont que "sucre syntaxique" ou un astuce de compilateur pour la fixation d'une méthode statique à une classe. Vous pouvez accomplir la même fin en créant simplement une méthode d'utilité statique normale dans une autre classe qui prend la classe souhaitée comme premier argument à la méthode. Je vois votre point sur "Ajout de" méthodes à une classe et de la standardiser ainsi, mais ce n'est pas vraiment ce qui se passe et que je trouve des méthodes d'extension pour être intuitives et pratiques pour ajouter des méthodes spécifiques à un domaine ou d'utilité à une classe existante cela serait autrement impossible.


1 commentaires

Mes pensées sont les suivantes: pour la «classe statique Wrapper» habituelle, vous savez qu'il y a une autre entité impliquée. Cela sera-t-il évident lors de l'utilisation de méthodes d'extension?



5
votes

Vous pouvez éteindre les cloches d'alarme. Les méthodes d'extension ne font qu'une très petite différence pour la syntaxe, et rien d'autre. Au lieu d'écrire: XXX PRE>

Vous écrivez: P>

public static void DisposeIfNotNull(this IDisposable d)
{
    if (d != null)
        d.Dispose();
}


2 commentaires

Il est étrange que ce dernier soit considéré comme sucre syntaxique pour le premier. Le premier ressemble beaucoup plus sucré pour moi, car il est clair, il dit ce qui se passe et il ne prétend pas faire de la magie.


Je suis juste curieux de savoir ce que vous pensez: j'aime vraiment utiliser une méthode d'extension qui définit "IN" afin que je puisse utiliser n'importe quel objet, tag A ".in () à la fin de celui-ci et de tester adhésion. Cela ressemble à une fonctionnalité de langue manquante pour moi. Souhaitez-vous considérer qu'un abus de méthodes d'extension?



1
votes

Je voulais soulever un peu un problème avec un point que vous avez dit. Les méthodes d'extension ne vous permettent pas d'ajouter des méthodes à une classe existante. Ils vous permettent de donner l'apparition d'ajouter une méthode à une classe existante. La distinction est subtile mais très importante.

maintenant pour aller contre les points que vous avez faits

  1. Je ne crois pas que cela soit vrai. Rien n'a changé quant à la protection de la bibliothèque. Les personnes utilisant vos méthodes d'extension verront une augmentation de la bibliothèque. Il modifie ou non que la norme de la bibliothèque dépend ou non de ce que vous faites dans vos méthodes.

  2. C'est simplement un moyen d'augmenter un type avec des méthodes sans changer son contrat d'origine.

  3. Je ne suis pas sûr de ce que vous entendez par portables, mais cela dépend probablement fortement de votre mise en œuvre. Si deux méthodes d'extension existent avec le même nom, ils passeront à la résolution de la surcharge et des erreurs seront soulevées de manière appropriée.

    L'utilisation et la définition des méthodes d'extension sont simplement du sucre syntaxique pour des méthodes statiques. Cela me permet de personnaliser un type faute d'un mot meilleur avec des méthodes spécifiques à mon domaine de problème ou simplement quelque chose qui manque autrement du framework d'origine ( ienumerable foreach par exemple ).

    Je ne trouve aucun argument de leur malness à être convaincant et je vais donc continuer à les utiliser parce que je les trouve productifs.


0 commentaires

2
votes

Je le regarde comme moyen commode de mettre en œuvre le motif de décorateur. Les méthodes d'extension vous permettent d'étendre un type en y ajoutant des méthodes. Bien sûr, ils sont portables entre projets si vous avez vos cours d'extension dans un assemblage séparé que vous pouvez partager.


0 commentaires

1
votes

D'autres ont déjà signalé le fait, que les méthodes d'extension ne modifient pas le type d'origine, alors simplement pour ajouter un peu: N'oubliez pas que les méthodes d'extension ne sont visibles que lorsque vous importez l'espace de nom défini. Donc, si vous «ajoutez» certaines méthodes à la chaîne, elles ne deviennent disponibles que lorsque vous les demandez explicitement. En d'autres termes, la portée des méthodes d'extension peut être contrôlée. Peut-être pas parfaitement, mais au moins ils ne font pas partie de nulle part où quelqu'un les ajoute à un projet.


1 commentaires

Merci, cela répond à une partie de la question énoncée dans mes commentaires ci-dessus.