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.
精彩评论