开发者

F# class constructor with no args --- error using filehelpers wtih f#

I followed the link of parse CSV using F# and filehelpers. got compiler error for the following code "The record class oneRow need a constructor with no args (public or private)"

[<DelimitedRecord(",")>]
type oneRow=
  class
    [<FieldConverter(ConverterKind.Date, "M/d/yyyy")>]
    val date: DateTime
    val value: bool
  end
let engine = new FileHelperEngine(typeof<oneRow>)
let tmp = engine.ReadFile("test.csv")

EDIT The solution looks quite verbose than c# version. I need add (), mutable and [<DefaultValue>]

  type oneRow() =
      class
        [<FieldConverter(ConverterKind.Date, "M/d/yyyy")>]
        [<DefaultValue>]
        val mutable date: Da开发者_高级运维teTime
        [<DefaultValue>]
        val mutable value: bool
      end

But similar code works in C# without specify a constructor. Could anyone help me fix the F# code? thanks.


C# will create you a constructor. F# doesn't (presumably because parameterless constructors imply mutability, and so are not exactly encouraged.)

For example, in your code - how are you going to set those properties, they're still immutable.


Regarding the verbose syntax - It can be made nicer. The sample was written some time ago (2 years), so it is still using a little old syntax. It could be updated to allow writing something like this:

[<DelimitedRecord(",")>]
type OneRow
   ( [<FieldConverter(ConverterKind.Date, "M/d/yyyy")>] 
     date:DateTime,
     value:bool ) =
   member x.Date = date
   member x.Value = value

I believe this is a lot nicer (and by moving annotations to the constructor, you can also implement your own functionality in the type and e.g. hide some fields). The only change that needs to be done is to modify the parser to find attributes on constructor parameters (and not fields).


Based on the error message, i think it would work if a ctor is added into oneRow.

new () = { date = new DateTime() ; value = false}


yes, it should be type oneRow () = with parentheses


Most of the posts concerning FileHelpers are rather dated. In some cases though it's nice to use instead of the csv type provider. One can use the CLIMutable attribute on an F# record to have a default constructor and in this case FileHelpers will happily write and read the csv file:

#if INTERACTIVE
#I @"..\packages\FileHelpers\lib\net45"
#r "FileHelpers.dll"
#endif

open FileHelpers
open System

[<DelimitedRecord(",");CLIMutable>]
type TestFileHelp =
    {test1:string
     test2:string
     [<FieldConverter(ConverterKind.Date, "yyyy/MM/dd")>]
     date:DateTime
    }

let f1 = [|{test1="a";test2="b";date=DateTime.Now};{test1="c";test2="d";date=DateTime.Now}|]
let fengine = new FileHelperEngine<TestFileHelp>()
fengine.WriteFile(@"c:\tmp\testrec.csv",f1)    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜