我正在尝试使用 JsonProvider,当我在其上调用函数时出现以下错误:

System.TypeInitializationException was unhandled
Message: An unhandled exception of type 'System.TypeInitializationException' occurred in PortableLibrary1.dll
Additional information: The type initializer for '<StartupCode$PortableLibrary1>.$PortableLibrary1' threw an exception.

我有一个基本的控制台应用程序,如下所示:
module Pinit =
   open FSharp.Data

   type JsonT = JsonProvider<"""..\myFile.json""">
   let doc = JsonT.Load("""..\nyFile.json""")
   let result = doc.GeneratedAt

[<EntryPoint>]
let main argv =
    printfn "%A" Pinit.doc.GeneratedAt
    0

在 ConsoleApplication 中运行时,一切都按预期工作。
如果我创建一个 F# 可移植类库,如下所示:
module Pinit =
   open FSharp.Data

   type JsonT = JsonProvider<"""..\myFile.json""">
   let doc = JsonT.Load("""..\nyFile.json""")
   let result = doc.GeneratedAt

创建另一个控制台应用程序并引用该可移植类库并按如下方式调用代码:
open PortableLibrary1

[<EntryPoint>]
let main argv =
    printfn "%A" Pinit.result
    0

当我运行程序时,它会生成上面定义的异常:

我怀疑这是因为 FSharp.Core 的版本,但想知道我是否做错了什么或者是否有办法让它工作?

版本:
-- ConsoleApplication --
FSharp.Core = 4.3.1.0

-- PortableClassLibrary --
FSharp.Core = 3.3.1.0
FSharp.Data = NuGet Version: 2.0.0

最佳答案

let 绑定(bind)被编译成静态成员,而在 .NET 中,当您在静态初始值设定项中出现异常时,真正的异常会被伪装。

如果您通过更改为 let result() = doc.GeneratedAtprintfn "%A" (Pinit.result()) 将其转换为函数调用,您将得到真正的异常:

Only web locations are supported

便携式配置文件不支持访问文件系统。因此,在 PCL 中,您可以拥有网址或从嵌入式资源手动加载。参见此处的示例: https://github.com/ovatsus/Apps/blob/master/Trains/Stations.fs#L65 。或者您可以在控制台项目中使用 File.ReadAllText 加载文件并将其传递给 PCL。

这是一个 Portable Profile (Legacy) 项目,即 Profile 47(和 FSharp.Core 2.3.6.0)。然后我还测试了一个 Portable Profile 项目,它是 Profile 7(和 FSharp.Core 3.3),并注意到它不能正常工作,而是给出了这个异常
Method not found: 'FSharp.Data.Runtime.JsonValueOptionAndPath FSharp.Data.Runtime.JsonRuntime.TryGetPropertyUnpackedWithPath(FSharp.Data.Runtime.IJsonDocument, System.String)'.

我创建了一个 github 问题来跟踪:https://github.com/fsharp/FSharp.Data/issues/521

关于f# - 在可移植类库中使用 F# JsonProvider 失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22364717/

10-12 17:43