This was non-trivial, as F# tries to prevent you from shooting yourself in the foot with recursive initialization. But here is what I did (the ToString and sample code are just to demo it works):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
type Foo private (tgt : Lazy<_>, dummy) =
    let mutable target = tgt

    public new() as self = Foo(lazy self, 0)
    public new(x) = Foo(lazy x, 0)

    member this.Target with get() = target.Value 
                       and set(x) = target <- lazy x

    override this.ToString() = string(this.GetHashCode())


let foo = new Foo()

printfn "%A" foo.Target 

let bar = new Foo(foo)

printfn "%A" bar.Target 
By on 6/9/2011 7:45 PM ()

thank you indeed - I didn't know you can make the primary constructor private in this way - this is VERY helpful.

By on 6/9/2011 9:44 PM ()
1
2
3
4
5
6
7
8
9
10
type Foo private (target : Lazy<Object>, dummy) =

    public new() as self = Foo(lazy self, 0)

    public new(x) = Foo(lazy x, 0)

    member this.Target = target

    override this.ToString() = string(this.GetHashCode())
By on 6/9/2011 9:54 PM ()

(The dummy param was to easily differentiate the private constructor, which takes a lazy, from the public one, that takes an object.)

Note that your final code has Target with type lazy, you want to have the RHS of the Target property call target.Value.

By on 6/9/2011 10:12 PM ()
1
2
3
4
5
type Foo private (target : Lazy<Object>, dummy) =
    public new() as self = Foo(lazy self, 0)
    public new(x) = Foo(lazy x, 0)
    member this.Target = target.Value
    override this.ToString() = string(this.GetHashCode())

Try the code above. It doesn't like the self argument because self is of type Foo and I have denoted type Object. The problem is I need it to be of type object and not of type Foo. How can I achieve this?

Thanks,

Scott

By on 6/10/2011 12:38 AM ()
1
2
3
4
5
6
7
type Foo private (target : Lazy<Object>, dummy) =
    public new() as self = Foo(lazy box self, 0)
    public new(x) = Foo(lazy x, 0)

    member this.Target : Object = target.Value

    override this.ToString() = string(this.GetHashCode())

I was able to answer my own question. For those who don't know, box is the keyword for upcasting to Object, the base class for all .NET languages. This completed my translation from C# to F#. Thanks so much for all your help.

Scott

By on 6/10/2011 1:03 AM ()

Wow, that would take me a long time to figure that out! Am i still required to use the mutable target you used in your example knowing I never want to change the binding of Target after initialization? Is it just required to get around the obstacles f# constructs, that you mentioned? Thanks for the help, btw.

The reason I want this is because this class will normally be inherited and want to just have a reference to myself in the Target. But I want to also support the cases where the user wants to point functionality at a class that hasn't inherited this one; if that makes sense.

Thanks

Scott

By on 6/9/2011 9:15 PM ()

Your original C# had get/set property, so I made it mutable in F# and mimicked that. You don't need the mutable if you don't want it, the code will get shorter/simpler (try it).

By on 6/9/2011 9:25 PM ()

Can you also explain why the dummy variable is necessary?

Thanks,

Scott

By on 6/9/2011 9:25 PM ()

I also realized that intellisense in my C# project reveals that the constructor takes type Foo rather than type object.

1
public object Target { get;set; }

The target member in the C# version was an object on purpose. I tried tweaking your solutions to have Lazy<_> changed to Lazy<Object> instead. But that wouldn't work. Ideas?

By on 6/9/2011 9:31 PM ()
1
2
3
4
5
6
7
type Foo private (target : Lazy<Object>, dummy) =
    public new() as self = Foo(lazy self, 0)
    public new(x) = Foo(lazy x, 0)

    member this.Target = target

    override this.ToString() = string(this.GetHashCode())
By on 6/9/2011 9:41 PM ()

nevermind. I found this:

[link:cs.hubfs.net]

What a pain

By on 6/9/2011 9:43 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us
Built with WebSharper