Contrôle d’accès

Le contrôle d’accès consiste à déclarer les clients qui peuvent utiliser certains éléments de programme, tels que des types, des méthodes et des fonctions.

Notions de base du contrôle d’accès

En F#, les spécificateurs de contrôle d’accès public, internal et private peuvent être appliqués aux modules, types, méthodes, définitions de valeurs, fonctions, propriétés et champs explicites.

  • public indique que l’entité est accessible à tous les appelants.

  • internal indique que l’entité n’est accessible qu’à partir du même assembly.

  • private indique que l’entité n’est accessible qu’à partir du type ou du module englobant.

Notes

Le spécificateur d’accès protected n’est pas utilisé en F#, bien qu’il soit acceptable si vous utilisez des types créés dans des langages qui prennent en charge l’accès protected. Par conséquent, si vous substituez une méthode protégée, votre méthode reste accessible uniquement dans la classe et ses descendants.

Le spécificateur d’accès est placé devant le nom de l’entité.

Si aucun spécificateur d’accès n’est utilisé, la valeur par défaut est public, sauf pour les liaisons let dans un type qui sont toujours private pour le type.

Les signatures en F# fournissent un autre mécanisme pour contrôler l’accès aux éléments de programme F#. Les signatures ne sont pas exigées pour le contrôle d’accès. Pour plus d’informations, consultez Signatures.

Règles de contrôle d’accès

Le contrôle d’accès est soumis aux règles suivantes :

  • Les déclarations d’héritage (c’est-à-dire l’utilisation de inherit pour spécifier une classe de base pour une classe), les déclarations d’interface (c’est-à-dire la spécification d’une classe pour implémenter une interface) et les membres abstraits ont toujours la même accessibilité que le type englobant. Un spécificateur de contrôle d’accès ne peut donc pas être utilisé sur ces constructions.

  • L’accessibilité pour des cas individuels dans une union discriminée est déterminée par l’accessibilité de l’union discriminée elle-même. Autrement dit, un cas d’union particulier n’est pas moins accessible que l’union elle-même.

  • L’accessibilité pour les champs individuels d’un type d’enregistrement est déterminée par l’accessibilité de l’enregistrement lui-même. Autrement dit, une étiquette d’enregistrement particulière n’est pas moins accessible que l’enregistrement lui-même.

Exemple

Le code suivant illustre l’utilisation des spécificateurs de contrôle d’accès. Le projet comprend deux fichiers : Module1.fs et Module2.fs. Chaque fichier est implicitement un module. Il y a donc deux modules : Module1 et Module2. Un type privé et un type interne sont définis dans Module1. Le type privé n’est pas accessible à partir de Module2, contrairement au type interne.

// Module1.fs

module Module1

// This type is not usable outside of this file
type private MyPrivateType() =
   // x is private since this is an internal let binding
   let x = 5
   // X is private and does not appear in the QuickInfo window
   // when viewing this type in the Visual Studio editor
   member private this.X() = 10
   member this.Z() = x * 100

type internal MyInternalType() =
   let x = 5
   member private this.X() = 10
   member this.Z() = x * 100

// Top-level let bindings are public by default,
// so "private" and "internal" are needed here since a
// value cannot be more accessible than its type.
let private myPrivateObj = new MyPrivateType()
let internal myInternalObj = new MyInternalType()

// let bindings at the top level are public by default,
// so result1 and result2 are public.
let result1 = myPrivateObj.Z
let result2 = myInternalObj.Z

Le code suivant teste l’accessibilité des types créés dans Module1.fs.

// Module2.fs
module Module2

open Module1

// The following line is an error because private means
// that it cannot be accessed from another file or module
// let private myPrivateObj = new MyPrivateType()
let internal myInternalObj = new MyInternalType()

let result = myInternalObj.Z

Voir aussi