クラス内の do バインディング (F#)
クラス定義内の do バインディングは、オブジェクトが構築されたとき、または型が最初に使用されたとき (静的な do バインディングの場合) にアクションを実行します。
[static] do expression
解説
do バインディングは、クラス定義で let バインディングと共に記述します。または、let バインディングの後、かつメンバー定義の前に記述します。 do キーワードは、モジュール レベルの do バインディングでは省略可能ですが、クラス定義の do バインディングでは省略できません。
指定された型のすべてのオブジェクトの構築では、静的でない do バインディングと静的でない let バインディングが、クラス定義に記述されている順に実行されます。 同じ型の do バインディングを複数、記述できます。 静的でない let バインディングと静的でない do バインディングが、プライマリ コンストラクターの本体になります。 静的でない do バインディング セクションのコードは、プライマリ コンストラクター パラメーターと、let バインディング セクションで定義されている値または関数を参照できます。
静的でない do バインディングがクラスのメンバーにアクセスできるのは、そのクラスに、クラスの見出しの as キーワードで定義されている自己識別子があり、そのメンバーが常にその自己識別子で修飾されて使用される場合のみです。
let バインディングはクラスのプライベート フィールドを初期化する (これは、多くの場合、メンバーが想定されたとおりに動作することを保証するために必要です) ため、do バインディングは、通常、let バインディングの後に記述します。これにより、do バインディングのコードを、完全に初期化されたオブジェクトで実行できます。 初期化が完了する前にコードでメンバーを使用しようとすると、InvalidOperationException が発生します。
静的な do バインディングでは、外側のクラスの静的メンバーまたは静的フィールドを参照できますが、インスタンス メンバーおよびインスタンス フィールドはいずれも参照できません。 静的な do バインディングはクラスの静的初期化子の一部になります。この初期化子は、必ず、そのクラスが最初に使用される前に実行されます。
型の do バインディングでは、属性は無視されます。 do バインディングで実行するコードに属性が必要な場合は、プライマリ コンストラクターに属性を適用する必要があります。
次のコードでは、クラスに静的な do バインディングと静的でない do バインディングがあります。 オブジェクトには、2 つのパラメーター (a と b) を持つコンストラクターがあり、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