访问控制 (F#)
“访问控制”是指声明哪些客户端能够使用特定程序元素,例如类型、方法和函数等。
访问控制基础知识
在 F# 中,可将访问控制说明符 public、internal 和 private 应用于模块、类型、方法、值定义、函数、属性和显式字段。
public 指示实体可由所有调用方访问。
internal 指示实体只能从同一程序集中进行访问。
private 指示实体只能从封闭类型或模块中进行访问。
备注
F# 中不使用访问说明符 protected,尽管在您使用通过不支持 protected 访问的语言编写的类型时,该说明符是可接受的。因此,如果您重写 protected 方法,则方法只能在类及其子代内访问。
通常,说明符放在实体名称的前面(使用 mutable 或 inline 说明符的情况除外,这些说明符出现在访问控制说明符的后面)。
如果未使用访问说明符,则默认值为 public(类型中的 let 绑定除外,这些绑定对于类型始终为 private)。
F# 中的签名提供了另一种机制,用于控制对 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