6
votes

Déclaration et mise en œuvre des membres de la classe C #

Y a-t-il un concept en C # de la définition de classe et de la mise en œuvre similaires à ce que vous trouvez en C ++?

Je préfère garder mes définitions de classe simples en supprimant la plupart des détails des implémentations (cela dépend de plusieurs facteurs que vous le savez, mais je vous déplace généralement vers la plupart des détails de la mise en œuvre du membre en dehors de la définition de la classe). Cela profite de me donner une vue à vol d'oiseau de la classe et de ses fonctionnalités.

Cependant, en C #, il semble que je suis obligé de définir mes fonctions de membre au point de déclaration. Peut-il être évité ou contourner une manière?

Au cours de mon apprentissage de C #, c'est un aspect qui me dérange. Les cours, surtout complexes, deviennent de plus en plus difficiles à lire.


0 commentaires

12 Réponses :


3
votes

Définir une interface.

Ensuite, il est agréable de pouvoir implémenter automatiquement l'interface à l'aide d'un outil d'assistance de code Nice.


1 commentaires

Ou une classe abstraite. Mais ce serait stupide.



3
votes

Vous pouvez obtenir un résultat similaire en définissant une interface pour chacune de vos classes qu'ils implémentent ensuite.


4 commentaires

D'accord. Je pense que je peux voir ton point. Utilisez-le comme mes types interfaces pour les classes, au lieu de classes. Pas exactement ce que j'espérais, mais bien sûr le tour. Cela a également répondu à ma question. :) Il n'y a pas de moyen de séparer les détails de la mise en œuvre des membres de la définition de la classe.


Les interfaces ne sont vraiment pas la bonne approche ici car elles ne peuvent contenir que les membres Public de la classe. Il n'y a aucun moyen d'obtenir le même résultat qu'un fichier d'en-tête dans C #.


Je n'irais pas après ce principe avec mes yeux fermés. Vous ne devez pas définir une interface pour la classe juste pour vous faciliter la lecture. Définir des interfaces sur tout le lieu peut faire le maintien de votre code un cauchemar.


Convenu définitivement. Pourquoi j'ai enregistré la possibilité mais n'a pas l'intention de la mettre en œuvre :)




7
votes

Si vous utilisez Visual Studio, vous pouvez profiter de la vue de la classe. Vous pouvez également utiliser les fonctionnalités Développer / Collapse de l'éditeur de code source.

Dans le cas improbable que vos outils ne vous aident pas, vous pouvez toujours écrire un utilitaire rapide qui résumera la classe pour vous.

Si la classe a été compilée, vous pouvez également utiliser le réflecteur pour voir la classe aussi.


1 commentaires

En outre, l'outil de diagramme de classe est plutôt bon pour obtenir une vue d'oiseau.



0
votes

Le prototypage que je suppose que vous faites référence à n'existe pas vraiment dans C #. Définir des interfaces Comme d'autres suggérons vous donnera un point où vous avez des déclarations de vos méthodes collectées, mais ce n'est pas la même chose que les prototypes, et je ne suis pas sûr que cela vous aidera à faciliter la lecture de vos cours de mise en œuvre. < / p>

c # n'est pas c ++ et ne devrait probablement pas être traité comme c ++.


2 commentaires

L'interface ne contiendra que les méthodes Public de la classe.


@Scott: Oui, c'est vrai, cela renforce l'argument selon lequel elle ne résout pas tout à fait la question soulevée dans la question.



7
votes

Non, il n'y a pas de concept de mise en œuvre et de fichiers d'en-tête en C # comme vous trouverez en C / C ++. Le plus proche que vous puissiez venir à ceci est d'utiliser une interface, mais l'interface ne peut définir que les membres du public de votre classe. Vous vous retrouveriez ensuite avec un mappage de 1 à 1 de classes et d'interfaces, ce qui n'est vraiment pas l'intention de savoir comment les interfaces doivent être utilisées.


0 commentaires

1
votes

Si vous constatez qu'une classe est difficile à lire ou difficile à comprendre, c'est souvent un signe que la classe tente de faire trop. Au lieu d'essayer de faire dupliquer la séparation des déclarations et des définitions de C ++, envisagez de refactore la classe gênante dans plusieurs classes afin que chaque classe ait moins de responsabilité.


1 commentaires

C'est très discutable BCAT. Cela dépend du domaine du problème.



1
votes

Chaque fois que c'est possible ou souhaitable, je vais aller avec les réponses précédentes et définir une interface. Mais ce n'est pas toujours approprié.

Alternativement, vous pouvez contourner ce "problème" en utilisant des outils d'inspection de code statiques. La fenêtre "Structure de fichiers" de Resharber vous donnera exactement ce que vous voulez. Vous pouvez également utiliser la "vue de la classe" intégrée à partir de Visual Studio. Mais je préfère le premier.


0 commentaires

4
votes

en C #, vous pouvez simuler avec des classes partielles et des membres partiels à un point, cependant, des déclarations et des prototypes en avant, passez la voie à l'oiseau Dodo avec vos nouvelles langues. Vue de classe, diagrammes de classe, IntelliSense, et al, toutes les aides à supprimer le besoin potentiel de ces "fonctionnalités".


0 commentaires

0
votes

Il y a deux remèdes pour cela pour le rendre plus C ++ - ISH:

  • Créer un fichier d'interface qui déclare toutes les signatures et propriétés de la méthode
  • Implémentez cette interface dans une classe sur plusieurs fichiers à l'aide du modificateur partiel sur les définitions de la classe

    modifications: xxx

    Le mode de séparation C ++ de séparer l'interface dans un fichier d'en-tête est principalement (je pense) en raison d'une décision de conception précoce lorsque c a été créé. Pour permettre des compilations incrémentielles rapides pendant les «vieux jours», lorsque le compilateur élimine les métadonnées, contrairement au SmallTalk. Ce n'est pas une question avec C # (ni Java) où des dizaines de milliers de lignes compile en quelques secondes sur le matériel récent (C ++ ne sont toujours pas)


0 commentaires

0
votes

Vous ne savez pas ce que vous entendez par vos classes continuez de croître et de devenir difficile à lire. Voulez-vous dire que vous voulez un fichier d'en-tête comme une vue des membres d'une classe? Si oui, comme le suggérait John, ne pouvez-vous pas simplement réduire la mise en œuvre afin que vous n'ayez pas à le voir?

Si vous ne voulez pas que chaque classe implémente une certaine chose, les interfaces sont probablement la voie à suivre (comme les autres disent).

mais comme une pensée latérale, si vos classes elles-mêmes deviennent de plus en plus complexes comme votre programme écrit, c'est peut-être plus d'une question de conception qu'un problème de langue? Je pense qu'une classe devrait avoir une responsabilité et ne pas prendre de plus en plus de responsabilités à mesure que le programme augmente, plutôt que le nombre de classes et la manière dont les classes sont utilisées devraient se développer et devenir plus complexes lorsque vous continuez à développer votre logiciel?


2 commentaires

Vous semblez vouloir mettre en œuvre la notion de contrat à une définition de classe. Ce raffinement n'est pas toujours possible, ni facile à réaliser. Une classe d'oiseaux doit voler, courir, caca, race, marcher, manger.


Je ne veux pas dire une notion de «contrat», juste que «testé» (ou un code déjà implémenté) doit être laissée seule (si possible) afin qu'un programme soit plus facile à lire et à entretenir. Par exemple, si vous souhaitez ajouter des fonctionnalités à oiseau, pourquoi ne pas simplement donner à Bird une collection de comportements (une interface). Chaque comportement (mouche / caca / etc.) mettrait en œuvre des comportements et serait mis en œuvre en dehors de l'oiseau, la mise en œuvre de l'oiseau n'aurait donc pas à changer et d'obtenir de nouvelles fonctionnalités. Je suis d'accord que ce n'est pas toujours possible, mais si vous pouvez prédire comment votre programme changera au fil du temps, vous pouvez concevoir cela?



8
votes

C'est vraiment un cas de besoin de reculer et de voir la plus grande image. Visual Studio possède de nombreux outils pour vous aider à écrire et à manipuler votre code, de décrivant, de figures, de la vue de classe, de diagrammes de classe, de la fenêtre de définition de code et de nombreuses autres.

C # n'est pas C ++, si vous essayez de le faire, alors vous allez faire trébucher sur vous-même et que personne d'autre ne pourra lire votre code.

Une journée passée à utiliser pour utiliser les outils Visual Studio remboursera l'investissement plusieurs fois en termes de productivité et vous vous demandera bientôt comment vous avez déjà vécu avec cette façon C ++ de faire des choses.

Mise à jour en réponse aux commentaires

Je suis depuis longtemps arrêté en ce qui concerne mon code sous forme de fichiers texte simples. Je considère que le code comme une chose organique et que je trouve que me permettant de s'appuyer sur une IDE riche en fonctionnalités me permet de monter et de réduire les niveaux d'abstraction plus facilement et améliore ma productivité sans fin. Je suppose que cela pourrait être un trait personnel et ce n'est peut-être pas pour tout le monde; J'ai un esprit très "visuel" et je travaille mieux quand je peux voir les choses en images.

Cela dit, une IDE intelligente n'est pas une excuse pour un style médiocre. Il y a de meilleures pratiques pour écrire "Clean Code" qui ne nécessitent pas d'IDE intelligent. L'un des principes du code de nettoyage est de conserver la définition de quelque chose près de son utilisation et je pense que cela pourrait être étendu pour couvrir la déclaration et la définition. Personnellement, je pense que la séparation de la déclaration et de la définition rend le code moins clair. Si vous constatez que vous obtenez des cours de monstres difficiles à comprendre, cela pourrait être un signe que vous violez le principe de responsabilité unique.

La raison de la définition et de la déclaration séparées en C / C ++ est que C ++ utilise un compilateur de passe unique, où les références avant ne peuvent pas être résolues ultérieurement, contrairement à C # et à son Compilateur à deux passes qui peut heurter des références indépendamment de l'ordre de déclaration. Cette différence découle des différentes design philosphies des compilateurs: C / C ++ considère que chaque fichier source constitue une unité de compilation, alors qu'en C #, l'ensemble du projet est considéré comme l'unité de compilation. Je suppose que lorsque vous êtes habitué à travailler sur la manière C / C ++, puis séparant la déclaration et la définition peut sembler être un élément souhaitable de style, mais je pense personnellement que la déclaration et l'utilisation (ou dans la présente déclaration et la définition) améliore, lutte plutôt, la lisibilité. J'avais l'habitude d'être un programmeur C moi-même jusqu'à ce que je commence à utiliser C # en 2001. J'ai toujours aimé c et pensais que c'est un moyen de faire les choses étaient les "Bees genoux". Ces jours-ci lorsque j'ai lu C / C ++ code, je pense qu'il a l'air absolument horrible et je ne peux pas croire que nous avions l'habitude de supporter de cette façon. C'est une question de ce que vous êtes habitué, je suppose.


1 commentaires

Je ne suis pas entièrement en désaccord avec toi Tim. Mais tandis que tout cela va bien et dandy, ce que cette philosophie signifie essentiellement que ce n'est que en présence d'un IDE riche en fonction, puis-je faire la tête et la queue de mon code. Maintenant ... ça me donne beaucoup de confort.