类中的 do 绑定

类定义中的 do 绑定在构造对象时执行操作;而静态 do 绑定则是在首次使用类型时执行操作。

语法

[static] do expression

备注

do 绑定出现的位置是:与 let 绑定一起(或它后面),但在类定义中的成员定义之前。 尽管 do 关键字对于模块级别的 do 绑定是可选的,但它对于类定义中的 do 绑定是不可选的。

对于任何给定类型的每个对象的构造,将按照非静态 do 绑定和非静态 let 绑定出现在类定义中的顺序来执行这两种绑定。 可以发生一种类型的多个 do 绑定。 非静态 let 绑定和非静态 do 绑定成为主构造函数的主体。 非静态 do 绑定部分中的代码可以引用主构造函数参数以及在 let 绑定部分中定义的任何值或函数。

只要类具有由类标题中的 as 关键字定义的自我标识符,并且只要使用类的自我标识符对类的成员的所有用法进行了限定,非静态 do 绑定就可以访问这些成员。

因为 let 绑定初始化类的专用字段(通常对于确保成员按预期方式运行是必需的),所以 do 绑定通常被放在 let 绑定后面,以便 do 绑定中的代码可使用完全初始化的对象执行操作。 如果你的代码尝试在初始化完成之前使用成员,则会引发 InvalidOperationException。

静态 do 绑定可以引用封闭类的静态成员或字段,但不能引用实例成员或字段。 静态 do 绑定成为类的静态初始值设定项的一部分,保证在第一次使用类之前执行。

对于类型中的 do 绑定,将忽略属性。 如果在 do 绑定中执行的代码需要一个属性,必须将该属性应用于主构造函数。

在下面的代码中,类具有静态 do 绑定和非静态 do 绑定。 对象具有一个有两个参数(ab)的构造函数,并且在类的 let 绑定中定义了两个专用字段。 还定义了两个属性。 它们全都在非静态 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

另请参阅