502 votes

Utilisations pratiques du mot-clé "internal" en C#

Pourriez-vous expliquer quelle est l'utilisation pratique de la internal en C# ?

Je sais que le internal limite l'accès à l'assemblage en cours, mais quand et dans quelles circonstances dois-je l'utiliser ?

437voto

Ash Points 31541

Classes/méthodes utilitaires ou auxiliaires auxquelles vous souhaitez accéder à partir de nombreuses autres classes au sein d'un même assemblage, mais auxquelles vous voulez vous assurer que le code d'autres assemblages ne peut pas accéder.

De MSDN (via archive.org) :

L'accès interne est souvent utilisé dans le cadre du développement de composants, car il permet à un groupe de composants de coopérer de manière privée sans être exposé au reste du code de l'application. Par exemple, un cadre pour la création d'interfaces utilisateur graphiques pourrait fournir des classes de contrôle et de formulaire qui coopèrent en utilisant des membres à accès interne. Comme ces membres sont internes, ils ne sont pas exposés au code qui utilise le framework.

Vous pouvez également utiliser le modificateur interne avec la fonction InternalsVisibleTo pour créer des assemblages "amis" qui bénéficient d'un accès spécial aux classes internes de l'assemblage cible.

Cela peut être utile pour la création d'assemblages de test unitaire qui sont ensuite autorisés à appeler des membres internes de l'assemblage à tester. Bien entendu, aucun autre assemblage ne se voit accorder ce niveau d'accès, de sorte que l'encapsulation est maintenue lorsque vous mettez votre système en production.

11 votes

L'attribut InternalsVisibleTo est d'une grande aide. Merci.

44 votes

J'ai le sentiment qu'à partir du moment où vous avez besoin de l'interne, il y a quelque chose qui ne va pas dans la conception quelque part. IMHO, on devrait pouvoir utiliser de l'OO pur pour résoudre tous les problèmes. En ce moment même, je suis en train de regarder la millionième utilisation d'internal dans les sources de .NET Framework, sans pouvoir tirer parti de ce qu'ils utilisent eux-mêmes. Grâce à l'utilisation d'internal, ils ont créé un monolithe qui est superficiellement modulaire, mais qui s'effondre lorsque vous essayez d'isoler des choses. De plus, la sécurité n'est pas un argument, car il y a la réflexion à la rescousse.

2 votes

En général, je suis d'accord avec vous. La seule exception est dans le cas de pouvoir construire des tests unitaires sans avoir à créer des accesseurs privés. Si vous voulez vérifier qu'une dépendance particulière a été correctement assignée, et que le champ contenant la dépendance n'est pas accessible publiquement, utiliser internal est la solution.

106voto

Eric Lippert Points 300275

Si Bob a besoin de BigImportantClass, il doit faire en sorte que les personnes qui possèdent le projet A s'engagent à garantir que BigImportantClass sera écrit pour répondre à ses besoins, testé pour s'assurer qu'il répond à ses besoins, documenté comme répondant à ses besoins, et qu'un processus sera mis en place pour s'assurer qu'il ne sera jamais modifié de manière à ne plus répondre à ses besoins.

Si une classe est interne, elle ne doit pas passer par ce processus, ce qui permet au Projet A d'économiser du budget qu'il peut consacrer à d'autres choses.

L'intérêt de l'interne n'est pas qu'il rende la vie difficile à Bob. C'est qu'il vous permet de contrôler les promesses coûteuses que le projet A fait sur les caractéristiques, la durée de vie, la compatibilité, et ainsi de suite.

8 votes

C'est parfaitement logique. J'aimerais juste que nous ayons la possibilité de passer outre les membres internes, car nous sommes tous des adultes consentants ici.

1 votes

@cwallenpoole : Vous le faites. InternalsVisibleToAttribute.

9 votes

@EricLippert Pas tout à fait ce que je voulais dire. Si j'hérite d'un code compilé qui contient "internal", je suis coincé, non ? Il n'y a aucun moyen de dire simplement au compilateur "Non, cet autre développeur vous a menti. Vous devriez me faire confiance à la place" à moins d'utiliser la réflexion.

69voto

Joel Mueller Points 14985

Une autre raison d'utiliser internal est si vous obfusquez vos binaires. L'obfuscateur sait qu'il est sûr de brouiller le nom de classe de toute classe interne, alors que le nom des classes publiques ne peut pas être brouillé, car cela pourrait casser les références existantes.

6 votes

Pff. En regardant le bytecode avec un désassembleur, on comprendra toujours très bien ce que fait le code de toute façon. Les obscurcisseurs ne sont qu'un léger moyen de dissuasion pour quiconque essaie vraiment de pénétrer dans les mécanismes internes. Je n'ai jamais entendu parler d'un hacker qui a arrêté juste parce qu'il n'a pas obtenu de noms de fonctions utiles.

46 votes

Donc tu ne verrouilles pas ta porte quand tu dors, parce que tu n'as jamais entendu parler d'un voleur arrêté par une serrure ?

9 votes

C'est pourquoi je brouille les noms de classes et de variables dans le code source. Vous êtes peut-être capable de comprendre ce qu'est un PumpStateComparator, mais pouvez-vous deviner ce qu'est un LpWj4mWE ? #jobsecurity (Je ne fais pas ça, et s'il vous plaît ne faites pas ça, les gens d'internet.)

40voto

Jeffrey L Whitledge Points 27574

Si vous écrivez une DLL qui encapsule une tonne de fonctionnalités complexes dans une simple API publique, alors "internal" est utilisé pour les membres de la classe qui ne doivent pas être exposés publiquement.

La dissimulation de la complexité (alias l'encapsulation) est le concept principal de l'ingénierie logicielle de qualité.

22voto

Augusto Radtke Points 2547

Le mot-clé internal est très utilisé lorsque vous construisez une enveloppe sur du code non géré.

Lorsque vous avez une bibliothèque basée sur C/C++ que vous voulez importer par DllImport, vous pouvez importer ces fonctions en tant que fonctions statiques d'une classe, et les rendre internes, afin que votre utilisateur n'ait accès qu'à votre wrapper et non à l'API d'origine, et qu'il ne puisse rien modifier. Les fonctions étant statiques, vous pouvez les utiliser partout dans l'assemblage, pour les multiples classes de wrapper dont vous avez besoin.

Vous pouvez jeter un coup d'œil à Mono.Cairo, c'est une enveloppe autour de la bibliothèque Cairo qui utilise cette approche.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X