Kontrola dostępu
Kontrola dostępu odnosi się do deklarowania, którzy klienci mogą używać niektórych elementów programu, takich jak typy, metody i funkcje.
Podstawy kontroli dostępu
W języku F# specyfikatory public
kontroli dostępu , internal
i private
mogą być stosowane do modułów, typów, metod, definicji wartości, funkcji, właściwości i jawnych pól.
public
wskazuje, że można uzyskać dostęp do jednostki przez wszystkich wywołujących.internal
wskazuje, że dostęp do jednostki można uzyskać tylko z tego samego zestawu.private
wskazuje, że dostęp do jednostki można uzyskać tylko z otaczającego typu lub modułu.
Uwaga
Specyfikator protected
dostępu nie jest używany w języku F#, chociaż jest akceptowalny, jeśli używasz typów utworzonych w językach, które obsługują protected
dostęp. W związku z tym, jeśli zastąpisz chronioną metodę, metoda pozostaje dostępna tylko w klasie i jej malejących.
Specyfikator dostępu jest umieszczany przed nazwą jednostki.
Jeśli nie jest używany żaden specyfikator dostępu, wartość domyślna to public
, z wyjątkiem let
powiązań w typie, które są zawsze private
typu.
Podpisy w języku F# zapewniają inny mechanizm kontrolowania dostępu do elementów programu języka F#. Podpisy nie są wymagane do kontroli dostępu. Aby uzyskać więcej informacji, zobacz Podpisy.
Reguły kontroli dostępu
Kontrola dostępu podlega następującym regułom:
Deklaracje dziedziczenia (czyli użycie
inherit
do określenia klasy bazowej dla klasy), deklaracje interfejsu (czyli określenie, że klasa implementuje interfejs) i abstrakcyjne elementy członkowskie zawsze mają taką samą dostępność jak otaczającego typu. W związku z tym specyfikator kontroli dostępu nie może być używany w tych konstrukcjach.Dostępność poszczególnych przypadków w unii dyskryminowanej jest określana przez dostępność samego związku dyskryminowanego. Oznacza to, że konkretny przypadek unii nie jest mniej dostępny niż sam związek.
Ułatwienia dostępu dla poszczególnych pól typu rekordu są określane przez dostępność samego rekordu. Oznacza to, że określona etykieta rekordu nie jest mniej dostępna niż sam rekord.
Przykład
Poniższy kod ilustruje użycie specyfikatorów kontroli dostępu. W projekcie znajdują się dwa pliki: Module1.fs
i Module2.fs
. Każdy plik jest niejawnie modułem. W związku z tym istnieją dwa moduły i Module1
Module2
. Typ prywatny i typ wewnętrzny są zdefiniowane w pliku Module1
. Nie można uzyskać dostępu do typu prywatnego z Module2
klasy , ale może to być typ wewnętrzny.
// 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
Poniższy kod testuje dostępność typów utworzonych w programie 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