Controllo dell’accesso
Il controllo di accesso si riferisce alla dichiarazione dei client che possono usare determinati elementi del programma, ad esempio tipi, metodi e funzioni.
Nozioni di base di Controllo di accesso
In F#, gli identificatori public
di controllo di accesso , internal
e private
possono essere applicati a moduli, tipi, metodi, definizioni di valori, funzioni, proprietà e campi espliciti.
public
indica che l'entità può essere accessibile da tutti i chiamanti.internal
indica che l'entità può essere accessibile solo dallo stesso assembly.private
indica che l'entità può essere accessibile solo dal tipo o dal modulo contenitore.
Nota
L'identificatore di protected
accesso non viene usato in F#, anche se è accettabile se si usano tipi creati in linguaggi che supportano protected
l'accesso. Pertanto, se si esegue l'override di un metodo protetto, il metodo rimane accessibile solo all'interno della classe e dei relativi discendenti.
L'identificatore di accesso viene inserito davanti al nome dell'entità.
Se non viene usato alcun identificatore di accesso, il valore predefinito è public
, ad eccezione let
delle associazioni in un tipo, che sono sempre private
al tipo .
Le firme in F# forniscono un altro meccanismo per controllare l'accesso agli elementi del programma F#. Le firme non sono necessarie per il controllo di accesso. Per altre informazioni, vedere Firme.
Regole per Controllo di accesso
Il controllo di accesso è soggetto alle regole seguenti:
Dichiarazioni di ereditarietà (ovvero l'uso di per specificare una classe di base per una classe), dichiarazioni di
inherit
interfaccia (ovvero, specificando che una classe implementa un'interfaccia) e i membri astratti hanno sempre la stessa accessibilità del tipo di inclusione. Pertanto, non è possibile utilizzare un identificatore di controllo di accesso in questi costrutti.L'accessibilità per i singoli casi in un'unione discriminata è determinata dall'accessibilità dell'unione discriminata stessa. Cioè, un caso di unione particolare non è meno accessibile rispetto all'unione stessa.
L'accessibilità per i singoli campi di un tipo di record è determinata dall'accessibilità del record stesso. Ovvero, una determinata etichetta di record non è meno accessibile del record stesso.
Esempio
Il codice seguente illustra l'uso degli identificatori di controllo di accesso. Nel progetto sono presenti due file e Module1.fs
Module2.fs
. Ogni file è implicitamente un modulo. Di conseguenza, sono disponibili due moduli e Module1
Module2
. Un tipo privato e un tipo interno sono definiti in Module1
. Non è possibile accedere al tipo privato da Module2
, ma il tipo interno può.
// 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
Il codice seguente verifica l'accessibilità dei tipi creati in 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