开发者

Define concise F# class with post constructor logic

开发者 https://www.devze.com 2022-12-20 21:45 出处:网络
For this class definition: type Foo(f1: int, f2: string) = member x.F1 = f1 member x.F2 = PostProcess f2

For this class definition:

type Foo(f1: int, f2: string) =
member x.F1 = f1
member x.F2 = PostProcess f2

Will PostProcess (some string manipulation function) gets called every time f2 is accessed? If the answer is yes and I want to avoid it, what’s the right idiom? Is this one below recommended? It is a bit too verbose for me.

type Foo =
val F1: int
va开发者_开发技巧l F2: string

new (f1, f2) as this = 
    {F1 = f1; F2 = f2;}
    then this.F2 = PostProcess(f2) |> ignore


In your original definition F2 is a read-only property and the PostProcess function will be called each time it is accessed. This is easy to verify:

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

Here's how I'd write the class to only process once:

type Foo(f1: int, f2: string) =
  let pf2 = PostProcess f2
  member x.F1 = f1
  member x.F2 = pf2


Yes, properties are re-evaluated every time (e.g. just like a get property in C#).

See @kvb's answer for a succinct answer to your particular question.

In general, see e.g.

http://msdn.microsoft.com/en-us/library/dd233192(VS.100).aspx

http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!894.entry

for language information on the best way to write class constructors. The concise summary is that you should use a 'primary constructor' (as you have, the parens right after the type name that take constructor arguments), and then use let and do at the top of the class as the constructor body.

0

精彩评论

暂无评论...
验证码 换一张
取 消