使用F#结果区分联合导致TypeLoadException

时间:2017-07-19 12:00:53

标签: f#

我重构了一些我要使用的代码(相对新引入的)F#结果类型,在FSharp.Core中定义如下:

type Result<'TOk,'TError> = 
| Ok of 'TOk 
| Error of 'TError

所有内容都会编译,但在运行时,应用程序会失败并出现以下异常:

  

无法从中加载“Microsoft.FSharp.Core.FSharpResult`2”类型   程序集'SomeAssembly,Version = 1.25.24.0,Culture = neutral,   由于值类型不匹配,PublicKeyToken = null。

如果我将定义复制到我的项目中,使其隐藏原始项目,那么一切正常。

app.config包含以下部分:

  <dependentAssembly>
    <Paket>True</Paket>
    <assemblyIdentity name="FSharp.Core" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="4.4.1.0" />
  </dependentAssembly>

项目文件使用指令<TargetFSharpCoreVersion>4.4.1.0</TargetFSharpCoreVersion>

进行更新

所以我不确定是什么原因导致这个错误。同样奇怪的是,错误消息声称FSharpResult应该驻留在项目程序集中,而不是FSharp.Core.dll。

更新。正如评论中所建议的那样,只有在使用Visual Studio 2015构建应用程序时才会出现问题。这是一个可以重现问题的小型控制台程序:

open System

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

打开Visual Studio 2015,构建并运行项目,您应该看到以下错误: 未处理的异常:System.TypeLoadException:无法加载类型 汇编中的'Microsoft.FSharp.Core.FSharpResult`2' 由于值类型不匹配,'ResultTest,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'。    在Program.main(String [] argv)

如果您使用Visual Studio 2017并使用它重建应用程序,该应用程序将正常工作并打印结果: 好“你好”

2 个答案:

答案 0 :(得分:8)

这是由F#4.0编译器与FSharp.Core 4.4.1.0一起使用引起的,如下所述:

https://github.com/Microsoft/visualfsharp/issues/3354

解决方法:只要使用Visual Studio 2015,就可以将FSharp.Compiler.Tools NuGet包添加到受影响的项目中。 Visual Studio 2017工作正常。

答案 1 :(得分:1)

就我而言,使用VS2015 IDE是必须的,所以我们实现了自己的Result类型版本:

type Result<'t, 'e> = | Ok of 't | Error of 'e

或者您甚至可以根据自己的错误处理要求微调类型,例如:

type Result<'t> =
        | Success of 't
        | Failure of (string * exn option) 

type Result<'t> =
        | Success of 't
        | Failure of (ErrorCode * string)
and ErrorCode = | Code1 | Code2 | Code3

我知道它并不理想,如果你在F#核心中有这种类型可以做得更好,但是它可以解决这个问题:)