对于此类定义:
type Foo(f1: int, f2: string) =
member x.F1 = f1
member x.F2 = PostProcess f2
每次访问f2时都会调用PostProcess(某些字符串操作函数)吗?如果答案是肯定的,我想避免它,那么什么是正确的习惯用法?这个是推荐的吗?这对我来说有点过于冗长。
type Foo =
val F1: int
val F2: string
new (f1, f2) as this =
{F1 = f1; F2 = f2;}
then this.F2 = PostProcess(f2) |> ignore
答案 0 :(得分:6)
在原始定义中,F2
是一个只读属性,每次访问时都会调用PostProcess
函数。这很容易验证:
let PostProcess s = printfn "%s" s; s
type Foo(f1: int, f2: string) =
member x.F1 = f1
member x.F2 = PostProcess f2
let f = Foo(1,"test")
let s1 = f.F2
let s2 = f.F2
以下是我将该课程编写为仅处理一次的方法:
type Foo(f1: int, f2: string) =
let pf2 = PostProcess f2
member x.F1 = f1
member x.F2 = pf2
答案 1 :(得分:1)
是的,每次都会重新评估属性(例如,就像C#中的get
属性一样。)
请参阅@ kvb的答案,以便对您的特定问题进行简洁的回答。
一般来说,参见例如
http://msdn.microsoft.com/en-us/library/dd233192(VS.100).aspx
http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!894.entry
有关编写类构造函数的最佳方法的语言信息。简明扼要的总结是,您应该使用“主要构造函数”(就像您所拥有的那样,在带有构造函数参数的类型名称后面的parens),然后在顶部使用let
和do
。 class作为构造函数体。