1

我按照下面描述的步骤读取 csv 但在最后一行出现运行时错误。
(TypeInitializationException)
谁能告诉我这里出了什么问题?

http://www.markstaples.com/2009/01/08/parsing-csv-files-in-f/

module ReadCsv //-------------------------------------  
open System  
open FileHelpers  
[<DelimitedRecord(",")>]  
[<IgnoreFirst(1)>]  
type CsvRecord =  
    class  
       val field1 : string  
    end

type oneRow() =  
    class  
        [<DefaultValue>]  
        val mutable Str1: string  
        [<DefaultValue>]  
       val mutable Str2: string  
   end

let engine = new FileHelperEngine(typeof<CsvRecord>)  
let res = engine.ReadFile("C:/Users/Admin/Desktop/test.csv")  

module main //--------------------------------  
let downcast_Customer_Array = Array.map (fun (a:obj) -> a :?> ReadCsv.CsvRecord)  
let res_Customers = downcast_Customer_Array ReadCsv.res  
4

1 回答 1

2

John 的评论正常,您可能正在尝试读取一个不存在的文件。在 Windows 中,反斜杠用于路径分隔,而不是(正)斜杠。这些反斜杠需要在 F# 字符串文字中进行转义。您看到这种情况的原因TypeInitializationException是该代码是在加载类型时执行的。如果它在一个函数中,它会在被调用时执行,你会得到预期的异常。

有几种方法可以转义反斜杠,选择一种:

let res = engine.ReadFile("C:\\Users\\Admin\\Desktop\\test.csv")
let res = engine.ReadFile(@"C:\Users\Admin\Desktop\test.csv")
let res = engine.ReadFile("""C:\Users\Admin\Desktop\test.csv""")

最后一个,三重引用,是 F# 3.0 的一部分。http://blogs.msdn.com/b/fsharpteam/archive/2012/07/19/more-about-fsharp-3.0-language-features.aspx

编辑 您的代码在类型初始化中运行的事实掩盖了您的真正错误。尝试以不同的方式构建代码:

module ReadCsv = //-------------------------------------  
   open System  
   open FileHelpers  

   [<DelimitedRecord(",")>]  
   [<IgnoreFirst(1)>]  
   type CsvRecord =  
       class  
          val field1 : string  
       end

   let read file = 
      let engine = new FileHelperEngine(typeof<CsvRecord>)  
      engine.ReadFile(file) 
      |> Array.map (fun row -> row :?> CsvRecord)

module Main = //--------------------------------  
    [<EntryPoint>]
    let main argv = 
       let results = ReadCsv.read "C:/Users/Admin/Desktop/test.csv"
       printfn "%A" results
       0 // return an integer exit code

现在,TypeInitializationException我们得到的不是BadUsageException消息“记录类 CsvRecord 需要一个没有参数(公共或私有)的构造函数”。更有用!解决这个问题,代码按预期工作:

module ReadCsv = //-------------------------------------  
   open System  
   open FileHelpers  

   [<DelimitedRecord(",")>]  
   [<IgnoreFirst(1)>]  
   type CsvRecord() =  
       class  
          [<DefaultValue>]
          val mutable field1 : string  
       end

   let read file = 
      let engine = new FileHelperEngine(typeof<CsvRecord>)  
      engine.ReadFile(file) 
      |> Array.map (fun row -> row :?> CsvRecord)

module Main = //--------------------------------  
    [<EntryPoint>]
    let main argv = 
       let results = ReadCsv.read "C:/Users/Admin/Desktop/test.csv"
       results |> Seq.iter (fun r -> printfn "%s" r.field1)
       0 // return an integer exit code
于 2012-12-21T14:27:46.927 回答