访问控制

访问控制是指声明哪些客户端可以使用某些程序元素,例如类型、方法和函数。

访问控制基础知识

在 F# 中,访问控制说明符 publicinternalprivate 可应用于模块、类型、方法、值定义、函数、属性和显式字段。

  • public 指示所有调用方都可以访问实体。

  • internal 指示只能从同一个程序集访问实体。

  • private 指示只能从封闭类型或模块访问实体。

注意

F# 中不使用访问说明符 protected,但是如果你使用通过支持 protected 访问的语言创作的类型,则可以接受该说明符。 因此,如果替代受保护的方法,你的方法仅在类及其后代中保持可访问状态。

访问说明符放在实体名称的前面。

如果未使用访问说明符,则默认使用 public,但类型中的 let 绑定除外,它们对该类型始终为 private

F# 中的签名提供另一种机制来控制对 F# 程序元素的访问。 访问控制不需要签名。 有关详细信息,请参阅签名

访问控制的规则

访问控制遵从以下规则:

  • 继承声明(即使用 inherit 指定类的基类)、接口声明(即指定类实现接口)和抽象成员始终具有与封闭类型相同的可访问性。 因此,不能在这些构造上使用访问控制说明符。

  • 可区分联合中单个案例的可访问性由可区分联合本身的可访问性决定。 也就是说,特定联合案例的可访问性不低于联合本身。

  • 记录类型的各个字段的可访问性由记录本身的可访问性决定。 也就是说,特定记录标签的可访问性不低于联合本身。

示例

下面的代码演示了访问控制说明符的用法。 项目中有两个文件:Module1.fsModule2.fs。 每个文件都隐式地用作模块。 因此,有两个模块:Module1Module2Module1 中定义专用类型和内部类型。 不能从 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

另请参阅