[英]FileHelpers BadUsageException only on compiled F# but not in script
我寫了一個fsi腳本,效果很好,並希望對其進行編譯,以便我可以更輕松地移動它。 但是,當我編譯它時,突然,FileHelpers開始出現錯誤。
以下代碼使用FileHelpers 2.9.9 。 這是一個最小的工作示例,用於說明問題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")
使用文件test.csv
作為
test1,1
test2,2
test3,3
如果我將代碼作為fsi .\\test.fsx
運行,它將可以正常工作。 但是,如果嘗試使用fsc .\\test.fsx
進行編譯並運行.\\test.exe
Unhandled Exception: FileHelpers.BadUsageException: The record class Type needs a constructor with no args (public or private)
出現錯誤: 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
為什么將其用作腳本但未編譯? 如果可能的話,我想保持不變。 感謝您的見解!
FSI使用System.Reflection.Emit即時編譯您的F#代碼。 似乎使用System.Reflection.Emit生成的類型始終至少具有一個構造函數(默認的公共構造函數或顯式定義的構造函數)。 因此,FSI發出的代碼要完全模仿完全沒有構造函數(既不是公共的也不是私有的)的編譯代碼的結果,是不可能的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.