クラス内の do 束縛

クラス定義の do バインドではオブジェクトが構築されたとき、静的 do バインドでは型が最初に使用されたときにアクションが実行されます。

構文

[static] do expression

解説

do バインドは、クラス定義の中で、let バインドと一緒かその後、ただしメンバー定義よりも前に現れます。 do キーワードは、モジュール レベルの do バインドに対しては省略可能ですが、クラス定義の do バインドでは省略可能ではありません。

所定の型の各オブジェクトを構築する際、非静的 do バインドと非静的 let バインドは、クラス定義に表示される順序で実行されます。 1 つの型で複数の do バインドを実行できます。 非静的 let バインドと非静的 do バインドは、プライマリ コンストラクターの本体になります。 非静的 do バインド セクションのコードは、プライマリ コンストラクターのパラメーターと、let バインド セクションで定義されている任意の値または関数を参照できます。

非静的 do バインドでは、クラスのメンバーにアクセスできます。ただし、そのクラスに、クラスの見出しで as キーワードによって定義されている自己識別子があり、かつそれらのメンバーの使用がすべて、そのクラスの自己識別子で修飾されている場合に限ります。

let バインドによってクラスのプライベート フィールドが初期化されるため (これは、メンバーが想定どおりに動作することを保証するためにしばしば必要となる)、通常は do バインドの後に let バインドが配置されます。これにより、do バインド内のコードが完全に初期化されたオブジェクトで実行できるようになります。 初期化が完了する前にコードによってメンバーの使用が試行されると、InvalidOperationException が発生します。

静的 do バインドでは、外部クラスの静的メンバーまたはフィールドを参照できますが、インスタンスのメンバーやフィールドを参照することはできません。 静的 do バインドはクラスの静的初期化子の一部となり、クラスが最初に使用される前に確実に実行されます。

型の do バインドでは、属性は無視されます。 do バインドで実行されるコードに属性が必要な場合は、プライマリ コンストラクターに適用する必要があります。

次のコードでは、クラスに静的 do バインドと非静的 do バインドがあります。 オブジェクトには、ab という 2 つのパラメーターを持つコンストラクターがあり、2 つのプライベート フィールドがクラスの let バインドで定義されています。 2 つのプロパティも定義されています。 これらはすべては、それらの値をすべて出力する行で示されているように、非静的 do バインド セクションのスコープ内にあります。

open System

type MyType(a:int, b:int) as this =
    inherit Object()
    let x = 2*a
    let y = 2*b
    do printfn "Initializing object %d %d %d %d %d %d"
               a b x y (this.Prop1) (this.Prop2)
    static do printfn "Initializing MyType."
    member this.Prop1 = 4*x
    member this.Prop2 = 4*y
    override this.ToString() = System.String.Format("{0} {1}", this.Prop1, this.Prop2)

let obj1 = new MyType(1, 2)

出力は次のとおりです。

Initializing MyType.
Initializing object 1 2 2 4 8 16

関連項目