I wrote an fsi script that worked great and wanted to compile it so that I could move it easier. However, when I compiled it, all of a sudden FileHelpers began giving errors.
The following code uses FileHelpers 2.9.9. It is a minimal working example to illustrate the issue, test.fsx
:
#r "FileHelpers.dll"
open FileHelpers
[<DelimitedRecord(",")>]
type Type =
val field1 : string
val field2 : int
override x.ToString() = sprintf "%s: %d" x.field1 x.field2
let readFile<'a> file = seq {
use engine1 = new FileHelperAsyncEngine(typeof<'a>)
use tmp1 = engine1.BeginReadFile(file)
engine1.ReadNext() |> ignore
while engine1.LastRecord <> null do
yield engine1.LastRecord :?> 'a
engine1.ReadNext() |> ignore
}
readFile<Type> "test.csv" |> Seq.iter (printfn "%A")
with the file test.csv
as
test1,1
test2,2
test3,3
If I run the code as fsi .\test.fsx
it will work fine. However, if I try to compile it with fsc .\test.fsx
and run .\test.exe
I get the error Unhandled Exception: FileHelpers.BadUsageException: The record class Type needs a constructor with no args (public or private)
. A work around that works in both scripting and compiled mode is
[<DelimitedRecord(",")>]
type Type () =
[<DefaultValue>]
val mutable field1 : string
[<DefaultValue>]
val mutable field2 : int
override x.ToString() = sprintf "%s: %d" x.field1 x.field2
Why would it work as a script but not compiled? I would like to keep it immutable if possible. Thanks for any insight!