简体   繁体   中英

F# - call method and assign to property in constructor

In F#, I am trying to write a class that has a constructor which calls a method and assigns the returned value to a property. Currently I can't get it to compile. This is my F# code:

namespace Model

type MyClass() = 
    do
        MyProperty <- GenerateString()

    member val public MyProperty = ""
        with get, set

    member public this.GenerateString() = 
        "this is a string"

The compile error is: FS0039 The value or constructor MyProperty is not defined.

What can I do to fix this?

I have pasted some C# code to demonstrate what I'm trying to do:

public class MyClass
{
    public string MyProperty { get; set; }

    public MyClass()
    {
        MyProperty = GenerateString();
    }

    private string GenerateString()
    {
        return "this is a string";
    }
}

You are getting the compiler error because you need to define a reference to the current instance of MyClass to use in the constructor. However, even if you do that, you'll find that the code fails at runtime:

type MyClass() as self = 
    do
        self.MyProperty <- self.GenerateString()

    member val public MyProperty = ""
        with get, set

    member public this.GenerateString() = 
        "this is a string"

This fails with the error System.InvalidOperationException: The initialization of an object or value resulted in an object or value being accessed recursively before it was fully initialized.

I would suggest using a local binding inside the class to house the property value, instead of trying to mutate a property of the class from inside the constructor. Something like this:

type MyClass() as self = 

    let mutable value = ""
    do value <- self.GenerateString()

    member public this.MyProperty
        with get() = value
        and set (v) = value <- v

    member public this.GenerateString() = 
        "this is a string"

Aaron gave a good answer but here's an alternative:

type MyClass() = 
    let genString () = "this is a string"
    member val public MyProperty = genString() with get, set
    member public this.GenerateString = genString

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM