À mon sens, le partial
mot-clé ne fait que permettre à une classe d'être divisée en plusieurs fichiers source. Y a-t-il une raison de faire cela autre que pour l'organisation du code? Je l'ai vu utilisé pour cela dans les classes d'interface utilisateur générées.
Cela semble une mauvaise raison de créer un mot clé complet. Si une classe est assez grande pour nécessiter plusieurs fichiers, elle en fait probablement trop. Je pensais que vous pourriez peut-être l'utiliser pour définir partiellement une classe pour un autre programmeur, mais il serait préférable de créer une classe abstraite.
c#
design
language-design
Michael K
la source
la source
partial
signifie seulement quelque chose quand il vient avantclass
. Vous pouvez l'utiliser comme identifiant dans d'autres parties du code, etc.Réponses:
Il est très utile dans tous les scénarios où une partie de la classe est générée par un outil personnalisé, car elle vous permet d'ajouter une logique personnalisée au code généré sans hériter de la classe générée. Btw. il existe également des méthodes partielles pour la même raison.
Cela ne concerne pas uniquement l'interface utilisateur, mais également d'autres technologies telles que Linq-To-Sql ou Entity Framework.
la source
Comme vous le dites, il est souvent utilisé pour séparer le code généré. Cela n'a souvent rien à voir avec la taille des classes / fichiers.
L’avantage de séparer le code généré en est un de style. Le code généré peut être assez moche et illisible et échouerait pour de nombreuses normes de codage (et contrôles StyleCop), mais ce n’est pas grave, personne n’a à le lire ni à le gérer directement. Ainsi, si vous le "cachez" dans un autre fichier, vous pouvez vous assurer que le reste de la classe est conforme aux normes, passe les contrôles StyleCop, etc.
Un autre domaine dans lequel j’ai utilisé c’est le cas où une classe implémente plusieurs interfaces. Il peut être très agréable de séparer l’implémentation en fichiers séparés, bien que ce soit plus une question de préférence personnelle, je n’ai jamais vu aucune norme de codage l’imposer ( ou empêcher) cela.
la source
L’un des développeurs où je travaille a été très utile il y a quelques semaines pour la refactorisation d’énormes classes divines incontrôlables et dotées de nombreuses méthodes publiques: en séparant les fonctions logiques de chaque la classe dans une classe partielle séparée, vous pouvez physiquement séparer la classe en unités plus atomiques qui devraient être les classes sans casser aucune fonctionnalité existante, ce qui vous permet de voir ce qui est commun et ce qui ne l’est pas. Avec cette première étape, vous pouvez plus facilement diviser les partiels en leurs propres classes indépendantes et les implémenter dans la base de code. Je pensais que c'était une bonne idée.
Cependant, en général, je pense qu'ils ne devraient être utilisés que pour augmenter les classes générées par la machine lors de l'écriture de nouveau code.
la source
Je peux penser à quelques scénarios utiles où les partiels ont un sens, la plupart d’entre eux que je m’utilise moi-même dans mes projets:
Pour séparer le code généré par Tool / IDE / Designer du code que vous gérez. Un bon exemple est le
Form.Designer.cs
fichier contenant le code généré par le concepteur pour les applications Windows Form. De nombreux autres formats .NET ont également un code généré par un outil, qui peut être potentiellement régénéré lorsque vous générez votre projet, de sorte que toutes vos modifications personnalisées seront effacées. La séparation vous aidera à protéger votre code et vos modifications de telles modifications automatisées.Lorsque vous implémentez plusieurs interfaces avec beaucoup de code dans l'implémentation. J'ai tendance à utiliser un fichier partiel séparé pour chaque interface, nommant comme ceci:
{Class}.{Interface}.cs
. Il est facile pour moi de voir dans l'EDI quelles interfaces{Class}
implémentent et comment.Lorsque la classe doit contenir une ou plusieurs classes imbriquées , en particulier avec suffisamment de code pour être placées dans un fichier séparé. Je voudrais coller au modèle ci-dessus et utiliser la
{Class}.{NestedClass}.cs
convention de nommage pour chaque classe imbriquée. Une réponse similaire est déjà mentionnée dans la réponse de Virtlink .Quand j'écris des
static
cours qui vont contenir des méthodes d'extension . Ce sera souvent le cas de fournir la même logique de méthode d'extension à des classes ou interfaces similaires, comme par exempleReverse
pour des collections génériques et non génériques. Je mettrais toutes les méthodes d'extension pour une seule classe ou interface dans un partiel séparé de la classe statique. Par exemple, j'aurais toutes les méthodes d'extension pour l'IList
interface à un endroit et les mêmes méthodes queIList<T>
dans un autre fichier. Une autre approche serait de mettre la même méthode (toutes ses surcharges) dans le même partiel, avec toutes les classes possibles pour lethis
paramètre - comme si vous aviez tous lesReverse
implémentations dans un fichier. Cela dépend de celui qui justifierait le mieux la séparation en termes de volume de code ou de conventions internes que vous ou votre organisation respecteriez peut-être.Je n’utilise pas cela, mais j’ai déjà vu des personnes en C / C ++ apprécier l’approche que je vais décrire ici: créez un partial pour la classe avec des méthodes partielles uniquement. Cela ressemble à la méthode C / C ++ pour définir les interfaces et séparer la déclaration de méthode de l'implémentation.
Séparation par des préoccupations purement logiques . Si vous travaillez avec une classe volumineuse combinant plusieurs ensembles d'opérations logiques, vous pouvez séparer chaque code lié logiquement en un partiel séparé. L'existence de telles classes va généralement à l'encontre du principe de séparation des préoccupations , mais on observe souvent des cas réels, en particulier pour des bases de code plus anciennes. Un autre utilisateur, Steve Evers, les a mentionnés dans sa réponse à cette question , les appelant dieu objets.. Personnellement, j’utilise l’approche des classes partielles pour scinder le code avant toute refactorisation de fichiers aussi volumineux, afin de faciliter mon travail et de rendre la refactorisation plus transparente. Cela réduira également les conflits que je pourrais éventuellement provoquer lorsque des systèmes de gestion de version tels que SVN sont impliqués.
la source
Je ne l'ai jamais vu mentionné par quiconque: j'avais l'habitude
partial
de mettre des classes imbriquées dans leurs propres fichiers.Tous mes fichiers de code ne contiennent qu'une seule classe, struct, interface ou enum. Il est beaucoup plus facile de trouver la définition d’un objet lorsque les noms de fichiers indiquent le nom de la chose recherchée. Et puisque Visual Studio essaie de faire correspondre les dossiers du projet aux espaces de noms, les noms de fichiers doivent correspondre aux classes.
Cela signifie également qu'une classe
NestedClass
imbriquée dansMyClass
aura propre fichier de dans mes projets:MyClass.NestedClass.cs
.la source
À l'exception de l'utilisation du code généré, je ne les ai jamais vus utilisés pour dissimuler des objets divins . Essayer de comprendre une nouvelle base de code ou de naviguer dans plusieurs fichiers source, qui sont le même objet, est tellement ennuyant.
Donc, quand vous demandez,
Why use partial classes?
je réponds: sauf si vous utilisez du code généré, ne le faites pas.la source
L'organisation du code est la seule raison, mais elle va plus loin qu'il n'y paraît au premier abord. Si vous avez des classes partielles où des pièces sont générées, vous pouvez facilement:
la source
Il existe également quelques endroits où les classes générées / impliquées sont déclarées partielles. Ainsi, si le développeur doit les étendre, elles ont un accès complet sans avoir à se soucier de l'héritage et de la neutralisation. Examinez les classes générées dans la zone temporaire asp.net après avoir exécuté un site de formulaires Web pour la première fois sous IIS si vous voulez essayer de saisir quelques exemples.
la source
Je peux penser à une utilisation sale pour eux.
Supposons que certaines classes nécessitent des fonctionnalités communes, mais que vous ne souhaitiez pas les intégrer à la chaîne d'héritage située au-dessus d'elles. Ou bien, vous avez un ensemble de classes utilisant une classe d'assistance commune.
Fondamentalement, vous voulez faire un héritage multiple, mais C # ne ressemble pas. Vous utilisez donc partial pour créer ce qui est essentiellement un #include en C / C ++;
Mettez toutes les fonctionnalités dans une classe ou utilisez la classe d'assistance. Copiez ensuite l’aide X fois et renommez-la en classe partielle A, B, C. et mettez partielle sur vos classes A, B, C.
Disclaimer: Oui, c'est mal. Ne le fais jamais - surtout si cela fâche d'autres personnes.
la source