F#的构造函数

F#的构造函数

 F#是.net中的函数编程语言,虽然,为了跟其它.net语言有更好的协作关系,F#本身也有相当的面向对象的功能,但是并不完整,有一些功能限制。譬如,不支持“protected”访问控制。再如,或算是一种特色,多构造函数中,必须其中一个为主构造函数,而其他构造函数只能调用主构造函数,这些构造函数称为“附加构造函数”。主构造函数必须写在最上方,微软建议按如下格式:

// This class has a primary constructor that takes three arguments
// and an additional constructor that calls the primary constructor.
 
type MyClass(x0, y0, z0) =
        let mutable x = x0 
        let mutable y = y0 
        let mutable z = z0 
        do 
            printfn "Initialized object that has coordinates (%d, %d, %d)" x y z 
        member this.X with get() = x and set(value) = x <- value 
        member this.Y with get() = y and set(value) = y <- value 
        member this.Z with get() = z and set(value) = z <- value 
        new() = MyClass(0, 0, 0)// Create by using the new keyword.

 
let myObject1 = new MyClass(1, 2, 3)

实际上,还有另外一种写法:

type MyClass =
    val mutable x : int
    val mutable y : int
    val mutable z : int
    
new(x0, y0, z0) = { x = x0; y = y0; z = z0 }
    member this.X with get () = this.x and set (value) = this.x <- value
    
member this.Y with get () = this.y and set (value) = this.y <- value
    member this.Z with get () = this.z and set (value) = this.z <- value
    
new() = MyClass(0, 0, 0)

let myObject1 = new MyClass(1, 2, 3) 

 




第二种的写法,只能在构造函数里面做赋值,而像第一种那样,支持let绑定和do绑定等等事情。微软建议采用第一种的写法,因为这样功能比较强大一点,甚至,在MSDN《构造函数(F#)》里面都不写明有下面的这种方法,只是在结构的构造函数里采用类似写法。不过,在另一篇《显式字段:val 关键字 (F#)》里则有提到。那么,为什么要提下面的那种方法呢?因为上面第一种方法有个缺陷,主构造函数没办法支持XML文档注释。
XML文档注释一般都写在代码的上一行,但是在type上一行,已经作为类的注释,所以已经地方标识主构造函数。
这个是微软真忘记了,解决问题可以,但是有点丑陋,就是在原来的主构造函数里面添加一个空的参数,而把原来的构造函数写成一个附加函数,调用新的构造函数,附加构造函数是可以注释的:

type MyClass(x0, y0, z0, u:unit) =
        let mutable x = x0 
        let mutable y = y0 
        let mutable z = z0 
        do 
            printfn "Initialized object that has coordinates (%d, %d, %d)" x y z 
        member this.X with get() = x and set(value) = x <- value 
        member this.Y with get() = y and set(value) = y <- value 
        member this.Z with get() = z and set(value) = z <- value 
    /// <summary>注释加在这里</summary> 
    /// <param name="x0">参数1</param>
    /// <param name="y0">参数2</param>
    /// <param name="z0">参数3</param>
 
      new(x0, y0, z0) = MyClass(x0, y0, z0, ()
        new() = MyClass(0, 0, 0)


另外,为了调用者的美观,我们还要把主构造函数隐藏起来,MSDN没介绍如何对这种构造函数做访问控制,private要加在类名和左括号之间,我搞了好久才知道,一般人我不告诉他:
type MyClass private (x0, y0, z0, u:unit) =
        let mutable x = x0 
        let mutable y = y0 
        let mutable z = z0 
        do 
            printfn "Initialized object that has coordinates (%d, %d, %d)" x y z 
        member this.X with get() = x and set(value) = x <- value 
        member this.Y with get() = y and set(value) = y <- value 
        member this.Z with get() = z and set(value) = z <- value 
    /// <summary>注释加在这里</summary> 
    /// <param name="x0">参数1</param>
    /// <param name="y0">参数2</param>
    /// <param name="z0">参数3</param>
 
      new(x0, y0, z0) = MyClass(x0, y0, z0, ()) 
        new() = MyClass(0, 0, 0)
 
这里加上私有访问控制,问题才算完美解决。
posted @ 2014-04-01 23:30  greatim  阅读(371)  评论(0编辑  收藏  举报