使用post构造函数逻辑定义简洁的F#类

时间:2010-02-19 19:12:19

标签: f# idioms

对于此类定义:

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

2 个答案:

答案 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),然后在顶部使用letdo。 class作为构造函数体。