2012-01-27 20 views
1

我写了伟大的工作,并希望编译它,这样我可以移动它更容易的FSI脚本。但是,当我编译它时,突然间FileHelpers开始出现错误。FileHelpers BadUsageException只在编译F#而不是在脚本

下面的代码使用FileHelpers 2.9.9。这是一个很小的工作的例子来说明这个问题,test.fsx:如果我运行代码fsi .\test.fsx它会正常工作与文件test.csv

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

test1,1 
test2,2 
test3,3 

。不过,如果我尝试用fsc .\test.fsx编译并运行.\test.exe我得到的错误Unhandled Exception: FileHelpers.BadUsageException: The record class Type needs a constructor with no args (public or private)。围绕一部作品工作在两个脚本和编译模式

[<DelimitedRecord(",")>] 
type Type() = 
    [<DefaultValue>] 
    val mutable field1 : string 
    [<DefaultValue>] 
    val mutable field2 : int 
    override x.ToString() = sprintf "%s: %d" x.field1 x.field2 

为什么它的工作作为一个脚本,但没有编制?我想尽可能保持不变。感谢您的任何见解!

回答

1

FSI使用System.Reflection.Emit编译上即时的F#代码。看起来用System.Reflection.Emit生成的类型总是至少有一个构造函数(默认的公共构造函数或显式定义的构造函数)。因此,它是不容易实现用于通过FSI发射到准确模仿经编译的代码,其在所有(均未公开也没有公开)没有构造的结果的代码。

+0

这是一种恼人的,但良好的了解。谢谢! – 2012-01-30 02:58:37