Управление доступом (F#)
Под управлением доступом понимается объявление того, какие клиенты могут использовать определенные элементы программы, например типы, методы и функции.
Основы управления доступом
В языке 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