f#中带有属性赋值的多个构造函数

问题描述:

我想要一个空构造函数和一个接受参数并将其分配给公共属性的构造函数重载。f#中带有属性赋值的多个构造函数

这是我坚持:

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; 

它给我的错误:在对象表达`意外的关键词“新”。预期的“成员”,“覆盖”或其他标记。

如果我使用member,物业TemplateDirectory给出了这样的错误:

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

你可以试试这个。

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

    new() = TemplateService("") 

    interface ITemplateService with 
     member this.TemplateDirectory = templateDirectory 
+0

如果我想在分配前检查'd'是空还是空,该怎么办?比如在它之前抛出一个错误。 – 2011-03-15 03:58:20

+0

请参阅Daniel编辑的版本进行空检查。 – 2011-03-15 04:51:26

+0

但我只需要为接受争论的构造函数做这个测试。如果我做'新的TemplateService()',那么它会抛出一个错误。 – 2011-03-15 05:04:14

不幸的是,如果你想使用接口并将值传递给构造函数nyinyithann答案是正确的。您可以像这样在构造函数中设置公共属性。

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") 

现在,如果你想使用一个接口,这将无法正常工作。我们不得不使用这个丑陋的东西。

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

我的建议是,当你想要接口和普通访问时,只需简单地定义它两次,一次在接口之外,并在接口中包装。 – Guvante 2011-03-15 19:24:55

你把在接口的定义构造函数,这是错误的原因。此外,您正尝试将值存储到仅获取属性,而应该使用后备存储。

最后,我会推荐nyinyithann的版本,因为它与通常的F#风格(最小可变)更直接,只是希望给一个更接近你的版本,以防万一它有帮助。

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;