En C#, chaque élément d'une bibliothèque ou d'un programme, qu'il s'agisse d'un type ou d'un membre de type, possède un niveau d'accessibilité. Ce niveau détermine si d'autres parties de votre code, au sein du même projet ou dans des projets référencés, peuvent interagir avec cet élément. Les modificateurs d'accès suivants permettent de définir cette visibilité lors de la déclaration :
public: Accessible depuis n'importe quel autre code, que ce soit dans le même projet ou dans des projets qui utilisent ce projet.private: Accessible uniquement depuis le code situé à l'intérieur de la même classe ou structure.protected: Accessible uniquement depuis le code de la même classe, de la même structure, ou des classes qui en héritent.internal: Accessible depuis n'importe quel code au sein du même projet, mais pas depuis des projets externes.protected internal: Accessible depuis le code du projet où il est déclaré, ainsi que depuis les classes qui en héritent dans d'autres projets. Cependant, pour y accéder depuis un autre projet, il faut passer par une instance de la classe dérivée, et l'accès doit se faire dans le contexte de cette classe dérivée.
Voici un exemple illustrant l'application de ces modificateurs à une classe et à ses membres :
public class Vehicle
{
public void Move()
{
// Méthode publique
}
private int currentSpeed;
protected void ApplyBrakes()
{
// Méthode protégée
}
internal void PerformMaintenance()
{
// Méthode interne
}
protected internal string GetStatus()
{
// Méthode protégée interne
return "Status OK";
}
}
Il est important de noter que tous les modificateurs ne peuvent pas être utilisés dans tous les contextes. La visibilité d'un membre est souvent contrainte par la visibilité de la classe ou de la structure qui le contient.
Visibilité des Classes et Structures
- Les classes et structures déclarées directement dans un espace de noms (non imbriquées) peuvent être
publicouinternal. Par défaut, leur visibilité estinternalsi aucun modificateur n'est spécifié. - Les membres de structures (y compris les classes et structures imbriquées) peuvent être
public,internalouprivate. Les membres de classes (y compris les types imbriqués) peuvent avoir tous les niveaux d'accès :public,protected internal,protected,internalouprivate. Par défaut, les membres de classes et de structures sontprivate. Les types imbriqués privés ne sont pas accessibles depuis l'extérieur du type conteneur. - La visibilité d'une classe dérivée ne peut pas être supérieure à celle de son type de base. Par exemple, une classe publique ne peut pas hériter d'une classe interne, car cela rendrait indirectement la classe de base accessible publiquement.
- L'attribut
InternalsVisibleToAttributepeut être utilisé pour autoriser d'autres projets spécifiés à accéder aux types marqués commeinternal.
Visibilité des Membres de Classes et Structures
- Toutes les cinq catégories d'accès peuvent être utilisées pour déclarer des membres de classes. Les membres de structures ne peuvent pas être déclarés comme
protectedcar les structures ne supportent pas l'héritage. - En général, la visibilité d'un membre ne peut pas dépasser celle du type qui le contient. Cependant, un membre public d'une classe interne peut être accessible depuis un projet externe si ce membre implémente une méthode d'interface ou surcharge une méthode virtuelle définie dans une classe de base publique.
- Le type de données des champs, propriétés ou événements doit avoir une visibilité au moins égale à celle du membre qui les contient. De même, le type de retour et les types des paramètres pour les méthodes, indexeurs ou délégués doivent avoir une visibilité au moins égale à celle du membre lui-même. Par exemple, une méthode publique ne peut pas retourner une instance d'une classe qui n'est pas publique. De même, un type privé ne peut pas avoir une propriété protégée.
- Les opérateurs définis par l'utilisateur doivent toujours être déclarés comme
public. - Les destructeurs ne peuvent pas avoir de modificateurs d'accès.
Voici un exemple de définition des niveaux d'accès pour les membres d'une classe :
public class VehicleAssembly
{
// Méthode protégée
protected void EngageDrive() { }
// Champ privé
private int numberOfWheels = 4;
// Propriété protégée interne
protected internal int Wheels
{
get { return numberOfWheels; }
}
}
Note sur protected internal : Cette combinaison signifie "protégé OU interne", et non "protégé ET interne". Ainsi, un membre protected internal est accessible depuis n'importe quelle classe du même projet (y compris les classes dérivées) et depuis les classes dérivées dans d'autres projets. Pour limiter l'accès aux seules classes dérivées du même projet, il faudrait déclarer la classe elle-même comme internal et ses membres comme protected.
Autres Types
- Les interfaces déclarées directement dans un espace de noms peuvent être
publicouinternal, par défautinternal, tout comme les classes et structures. Les membres d'une interface sont toujousrpublicpar nature, car le but d'une interface est de définir un contrat accessible par d'autres types. Les modificateurs d'accès ne s'appliquent pas aux membres d'interface. - Les membres d'une énumération (
enum) sont toujourspublicet ne peuvent pas se voir attribuer de modificateurs d'accès. - Les délégués fonctionnent de manière similaire aux classes et structures. Par défaut, ils ont une accessibilité
internallorsqu'ils sont déclarés directement dans un espace de noms, etprivatelorsqu'ils sont imbriqués.