Zugriffssteuerung
Zugriffssteuerung bedeutet, dass deklariert wird, welche Clients bestimmte Programmelemente wie Typen, Methoden und Funktionen verwenden können.
Grundlagen der Zugriffssteuerung
In F# können die Zugriffssteuerungsspezifizierer public
, internal
und private
auf Module, Typen, Methoden, Wertdefinitionen, Funktionen, Eigenschaften und explizite Felder angewendet werden.
public
gibt an, dass alle Aufrufer auf die Entität zugreifen können.internal
gibt an, dass nur von derselben Assembly aus auf die Entität zugegriffen werden kann.private
gibt an, dass nur vom einschließenden Typ oder Modul aus auf die Entität zugegriffen werden kann.
Hinweis
Der Zugriffsspezifizierer protected
wird in F# nicht verwendet. Er ist jedoch zulässig, wenn Sie Typen verwenden, die in Sprachen erstellt wurden, die den protected
-Zugriff unterstützen. Wenn Sie also eine geschützte Methode überschreiben, kann auf die Methode nur noch innerhalb der Klasse und ihrer Nachfolger zugegriffen werden.
Der Zugriffsspezifizierer wird dem Namen der Entität vorangestellt.
Wenn kein Zugriffsspezifizierer verwendet wird, ist public
der Standardwert, mit Ausnahme von let
-Bindungen in einem Typ, die immer private
für den Typ sind.
Signaturen in F# sind eine weitere Möglichkeit, den Zugriff auf F#-Programmelemente zu steuern. Signaturen sind für die Zugriffssteuerung nicht erforderlich. Weitere Informationen finden Sie unter Signaturen.
Regeln für die Zugriffssteuerung
Die Zugriffssteuerung unterliegt den folgenden Regeln:
Für Vererbungsdeklarationen (d. h. die Verwendung von
inherit
, um eine Basisklasse für eine Klasse anzugeben), Schnittstellendeklarationen (d. h. die Angabe, dass eine Klasse eine Schnittstelle implementiert) und abstrakte Member gelten immer die gleichen Zugriffsregeln wie für den einschließenden Typ. Daher kann für diese Konstrukte kein Zugriffssteuerungsspezifizierer verwendet werden.Der Zugriff auf einzelne Fälle in einer diskriminierten Union wird durch den Zugriff auf die diskriminierte Union selbst bestimmt. Das heißt, dass der Zugriff auf einen bestimmten Unionfall nicht eingeschränkter als der Zugriff auf die Union selbst sein kann.
Der Zugriff auf einzelne Felder in einem Datensatztyp wird durch den Zugriff auf den Datensatz selbst bestimmt. Das heißt, dass der Zugriff auf eine bestimmte Datensatzbezeichnung nicht eingeschränkter als der Zugriff auf den Datensatz selbst sein kann.
Beispiel
Der folgende Code veranschaulicht die Verwendung von Zugriffssteuerungsspezifizierern. Es gibt zwei Dateien im Projekt, Module1.fs
und Module2.fs
. Jede Datei ist implizit ein Modul. Daher gibt es zwei Module, Module1
und Module2
. Ein privater Typ und ein interner Typ werden in Module1
definiert. Auf den privaten Typ kann nicht über Module2
zugegriffen werden, auf den internen Typ jedoch schon.
// 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
Der folgende Code testet den Zugriff auf die in Module1.fs
erstellten Typen.
// 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