3

我按照使用 F# 和 filehelpers 解析 CSV的链接。得到以下代码的编译器错误"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")

编辑 该解决方案看起来比 c# 版本非常冗长。我需要添加()mutable并且[<DefaultValue>]

  type oneRow() =
      class
        [<FieldConverter(ConverterKind.Date, "M/d/yyyy")>]
        [<DefaultValue>]
        val mutable date: DateTime
        [<DefaultValue>]
        val mutable value: bool
      end

但是类似的代码可以在 C# 中工作,而无需指定构造函数。谁能帮我修复 F# 代码?谢谢。

4

5 回答 5

2

C# 将为您创建一个构造函数。F# 没有(可能是因为无参数构造函数意味着可变性,因此不完全鼓励。)

例如,在您的代码中 - 您将如何设置这些属性,它们仍然是不可变的。

于 2011-02-11T16:10:24.523 回答
2

关于冗长的语法 - 它可以做得更好。该示例是在一段时间前(2 年)编写的,所以它仍然使用有点旧的语法。可以更新它以允许编写如下内容:

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

我相信这更好(并且通过将注释移动到构造函数,您还可以在类型中实现自己的功能,例如隐藏一些字段)。唯一需要做的更改是修改解析器以查找构造函数参数(而不是字段)的属性。

于 2011-02-11T16:44:37.700 回答
0

是的,它应该type oneRow () =带括号

于 2011-02-11T16:08:34.993 回答
0

根据错误消息,我认为如果将 ctor 添加到 oneRow 中它会起作用。

new () = { date = new DateTime() ; value = false}
于 2011-02-11T16:09:05.057 回答
0

大多数关于 FileHelpers 的帖子都过时了。在某些情况下,尽管使用它代替 csv 类型提供程序很好。可以使用CLIMutableF# 记录上的属性来拥有默认构造函数,在这种情况下,FileHelpers 将愉快地写入和读取 csv 文件:

#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)    
于 2016-12-29T06:20:52.723 回答