Multiple Constructors in f# with property assignment

心已入冬 提交于 2019-12-14 03:49:50

问题


I want to have a constructor that is blank and a constructor overload that accepts a parameter and assign it to a public property.

This is where I am stuck:

type TemplateService() = 
    interface ITemplateService with

        //Properties
        member TemplateDirectory = ""

        //Constructors
        new (templateDirectory:string) = //Error here.
            if (templateDirectory == null) then
                raise (new System.ArgumentNullException("templateDirectory"))
            TemplateDirectory = templateDirectory;

It gives me the error: `Unexpected keyword 'new' in the Object expression. Expected 'member', 'override' or other token.

If I use member, the property TemplateDirectory gives this error:

This instance member needs a parameter to represent the object being invoked. Make the member static or use the notation 'member x.Member(args) = ...'


回答1:


You could try this.

type TemplateService(templateDirectory : string) = 
    do
        if templateDirectory = null then nullArg "templateDirectory"

    new() = TemplateService("")

    interface ITemplateService with
        member this.TemplateDirectory = templateDirectory



回答2:


Unfortunately if you want to use an interface and pass the value to the constructor nyinyithann answer is correct. You can set public properties in a constructor call like this.

type TemplateService() = 
    let mutable templateDirectory = ""

    member this.TemplateDirectory
        with get() = templateDirectory
        and set directory = 
            if directory = null then
                raise (new System.ArgumentNullException "templateDirectory")
            templateDirectory <- directory

let template = TemplateService(TemplateDirectory = "root")

Now if you want to use an interface this won't work.

type ITemplateService =
     abstract TemplateDirectory : string with get, set

type TemplateService() = 
    let mutable templateDirectory = ""

    interface ITemplateService with
        member this.TemplateDirectory
            with get() = templateDirectory
            and set directory = 
                if directory = null then
                    raise (new System.ArgumentNullException "templateDirectory")
                templateDirectory <- directory

let template = TemplateService(TemplateDirectory = "root") // error

You're forced to use this ugly thing.

let template = TemplateService()
(template :> ITemplateService).TemplateDirectory <- "root"



回答3:


You are putting your constructor in the definition of the interface, and that is the cause for the error. Also you are attempting to store a value to a get only property, instead you should use a backing store.

Finally I would recommend nyinyithann's version over this, since it is more inline with the usual F# style (minimal mutables), just hoping to give a version closer to yours in case it is helpful.

type TemplateService() = 
    let mutable directory = ""

    interface ITemplateService with

        //Properties
        member this.TemplateDirectory = directory

    //Constructors
    new (templateDirectory:string) =
        if (templateDirectory = null) then
            raise (new System.ArgumentNullException("templateDirectory"))
        directory <- templateDirectory;


来源:https://stackoverflow.com/questions/5307252/multiple-constructors-in-f-with-property-assignment

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!