アクセス制御

アクセス制御 とは、特定のプログラム要素 (型、メソッド、関数など) を使用できるクライアントを宣言することを指します。

アクセス制御の基礎

F# では、アクセス制御指定子 publicinternalprivate を、モジュール、型、メソッド、値の定義、関数、プロパティ、明示的なフィールドに適用することができます。

  • public は、そのエンティティにすべての呼び出し元からアクセスできることを示します。

  • internal は、そのエンティティが同じアセンブリからのみアクセスできることを示します。

  • private は、そのエンティティが、それを囲む型またはモジュールからのみアクセスできることを示します。

注意

アクセス指定子 protected は F# では使用されませんが、protected アクセスをサポートする言語で作成された型を使用している場合は許容されます。 したがって、保護されたメソッドをオーバーライドすると、そのメソッドはクラスとその子孫内でのみアクセス可能な状態になります。

一般に、指定子は、エンティティの名前の前に置きます。ただし、mutable または inline 指定子を使用する場合は、それらをアクセス制御指定子の後に置きます。

アクセス指定子を使用しない場合、既定値は public です。ただし、型の let バインドは例外で、型に対して常に private になります。

F# のシグネチャは、F# プログラム要素へのアクセスを制御するための別の機構を提供します。 アクセス制御にシグネチャは必須ではありません。 詳細については、「シグネチャ」を参照してください。

アクセス制御の規則

アクセス制御には、次の規則が適用されます。

  • 継承宣言 (inherit を使用してクラスの基底クラスを指定)、インターフェイス宣言 (クラスがインターフェイスを実装することを指定)、抽象メンバーは、それを囲む型と同じアクセス可能性を常に持ちます。 したがって、これらのコンストラクトではアクセス制御指定子を使用できません。

  • 判別共用体の個々のケースのアクセス可能性は、判別共用体そのもののアクセス可能性によって決まります。 つまり、特定の共用体ケースは、共用体そのもののアクセス可能性より低くはなりません。

  • レコード型の個々のフィールドのアクセス可能性は、レコードそのもののアクセス可能性によって決まります。 つまり、特定のレコード ラベルは、レコードそのもののアクセス可能性より低くはなりません。

次のコードは、アクセス制御指定子の使用例を示しています。 このプロジェクトには、2 つのファイル Module1.fs および Module2.fs があります。 各ファイルは暗黙的にモジュールです。 したがって、Module1Module2 という 2 つのモジュールがあります。 Module1 では、private 型と internal 型が定義されています。 Module2 から private 型にはアクセスできませんが、internal 型にはアクセスできます。

// 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

関連項目