tags:

views:

146

answers:

2

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
val F2: string

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

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
kvb
Perfect! I also verified myself. And your proposal looks good and concise.
vha14
+1  A: 

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.

Brian
Thanks Brian for the pointers. I am just starting to use the OOP aspects of F#.
vha14