Contrôle d'accès (F#)
Le contrôle d'accès fait référence à la déclaration de clients qui peuvent utiliser certains éléments de programme, tels que des types, des méthodes et des fonctions.
Concepts 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 à des modules, des types, des méthodes, des définitions de valeur, des fonctions, des propriétés et des champs explicites.
public indique que l'entité est accessible par tous les appelants.
internal indique que l'entité est uniquement accessible à partir du même assembly.
private indique que l'entité est uniquement accessible à partir du type ou module englobant.
Notes
Le spécificateur d'accès protected n'est pas utilisé en F#, bien que ceci 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.
En général, le spécificateur est placé devant le nom de l'entité, sauf lorsqu'un spécificateur mutable ou inline est utilisé, qui apparaît après le spécificateur de contrôle d'accès.
Si aucun spécificateur d'accès n'est utilisé, la valeur par défaut est public, à l'exception des liaisons let dans un type, qui sont toujours private pour le type.
En F#, les signatures constituent un autre mécanisme de contrôle de l'accès aux éléments de programme F#. Les signatures ne sont pas obligatoires pour le contrôle d'accès. Pour plus d'informations, consultez Signatures (F#).
Règles pour le 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 d'inherit pour spécifier une classe de base pour une classe), les déclarations d'interface (c'est-à-dire spécifier qu'une classe implémente une interface) et les membres abstraits ont toujours la même accessibilité que le type englobant. Par conséquent, un spécificateur de contrôle d'accès ne peut pas être utilisé sur ces constructions.
Des cas individuels dans une union discriminée ne peuvent pas avoir leurs propres modificateurs de contrôle d'accès dans un emplacement distinct du type d'union.
Les champs individuels d'un type d'enregistrement ne peuvent pas avoir leurs propres modificateurs de contrôle d'accès séparés du type d'enregistrement.
Exemple
Le code suivant illustre l'utilisation de spécificateurs de contrôle d'accès. Le projet contient deux fichiers : Module1.fs et Module2.fs. Chaque fichier est implicitement un module. Par conséquent, il y a deux modules : Module1 et Module2. Un type privé et un type interne sont définis dans Module1. Contrairement au type interne, le type privé n'est pas accessible à partir de Module2.
// 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