Управление доступом
Управление доступом означает объявление клиентов, которые могут использовать определенные элементы программы, такие как типы, методы и функции.
Основы контроль доступа
В F# описатели управления доступом public
, internal
и private
могут применяться к модулям, типам, методам, определениям значений, функциям, свойствам и явным полям.
public
указывает, что к сущности могут обращаться все вызывающие абоненты.internal
указывает, что доступ к сущности можно получить только из той же сборки.private
указывает, что доступ к сущности можно получить только из включающего типа или модуля.
Примечание
Описатель protected
доступа не используется в F#, хотя это допустимо, если вы используете типы, созданные на языках, поддерживающих protected
доступ. Поэтому при переопределении защищенного метода метод остается доступным только в пределах класса и его потомков.
Как правило, описатель помещается перед именем сущности, за исключением случаев, когда mutable
используется описатель или inline
, который отображается после описателя управления доступом.
Если описатель доступа не используется, по умолчанию используется public
значение , за let
исключением привязок в типе , которые всегда private
относятся к типу .
Сигнатуры в F# предоставляют еще один механизм управления доступом к элементам программы F#. Подписи не требуются для управления доступом. Дополнительные сведения см. в статье Сигнатуры.
Правила для контроль доступа
Управление доступом регулируется следующими правилами:
Объявления наследования (то есть использование
inherit
для указания базового класса для класса), объявления интерфейса (то есть указание того, что класс реализует интерфейс) и абстрактные члены всегда имеют те же специальные возможности, что и включающий тип. Таким образом, описатель управления доступом нельзя использовать в этих конструкциях.Доступность отдельных случаев в дискриминируемом союзе определяется доступностью самого дискриминационного союза. То есть, конкретный случай объединения не менее доступен, чем сам союз.
Доступность для отдельных полей типа записи определяется доступностью самой записи. То есть определенная метка записи не менее доступна, чем сама запись.
Пример
В следующем коде показано использование описателей управления доступом. В проекте есть два файла: Module1.fs
и Module2.fs
. Каждый файл неявно является модулем. Таким образом, существует два модуля: Module1
и Module2
. Закрытый и внутренний тип определяются в Module1
. Закрытый тип не может быть получен из 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
Следующий код проверяет доступность типов, созданных в 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