简体   繁体   English

没有args的F#类构造函数 - 使用filehelpers与f#时出错

[英]F# class constructor with no args — error using filehelpers wtih f#

I followed the link of parse CSV using F# and filehelpers . 使用F#和filehelpers跟踪了解析CSV的链接。 got compiler error for the following code "The record class oneRow need a constructor with no args (public or private)" 得到以下代码的编译器错误"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. 编辑该解决方案看起来比c#版本相当冗长。 I need add () , mutable and [<DefaultValue>] 我需要add ()mutable[<DefaultValue>]

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

But similar code works in C# without specify a constructor. 但是类似的代码在C#中工作而没有指定构造函数。 Could anyone help me fix the F# code? 任何人都可以帮我修复F#代码吗? thanks. 谢谢。

C# will create you a constructor. C#将创建一个构造函数。 F# doesn't (presumably because parameterless constructors imply mutability, and so are not exactly encouraged.) F#没有(大概是因为无参数构造函数意味着可变性,因此并不完全鼓励。)

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. 该样本是在前一段时间(2年)编写的,所以它仍然使用一些旧的语法。 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 eg 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). 唯一需要做的更改是修改解析器以查找构造函数参数(而不是字段)的属性。

Most of the posts concerning FileHelpers are rather dated. 关于FileHelpers的大多数帖子都过时了。 In some cases though it's nice to use instead of the csv type provider. 在某些情况下,虽然使用而不是csv类型提供程序很好。 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: 可以使用F#记录上的CLIMutable属性来创建默认构造函数,在这种情况下,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)    

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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