F#Guid.Parse TypeInitializationException

时间:2017-10-13 13:43:22

标签: exception f#

我正在使用F#编写的WebApi项目。这是一个片段:

module MyModule

open System

let MyGuid = Guid.Parse "934F0B12-D00A-491D-862D-EE745EF3C560"

let myFunction list = 
    list.Get(MyGuid) // --> here MyGuid has the TypeInitializationException before list.Get is called 

通过调试我可以看到MyGuid实际上有错误

更改代码如下,它有效:

module MyModule

open System

let MyGuid () = Guid.Parse "934F0B12-D00A-491D-862D-EE745EF3C560"

let myFunction list = 
    list.Get(MyGuid())

我实际上知道第一个例子的MyGuid是一个变量而第二个是函数定义,但为什么第一个例子会引发异常呢?我的代码MyGuid有时会被使用。所以在第一个例子中,我只有一个实例,第二个是每次调用MyGuid的新实例...

1 个答案:

答案 0 :(得分:2)

我不是100%确定这是问题所在,但我有时会看到类似的行为。我的猜测是错误发生是因为顶级MyGuid变量未正确初始化并且具有默认的零值(因此,查找失败)。

全局变量在F#中初始化的方式很棘手 - 如果将代码编译为可执行文件,则可以从Main方法进行。但是,如果将代码编译为库,则编译器会将初始化检查插入到库中类型的静态构造函数中(以确保在访问任何内容之前初始化所有内容)。

我认为如果将代码编译为可执行文件,然后将其作为库加载,则可能会中断 - 不会调用入口点,因此不会初始化变量。我不确定WebApi究竟是如何加载库的,但这可能是一个问题 - 特别是如果您将F#代码编译为可执行文件。

将全局变量转换为函数的解决方法解决了这个问题,因为函数被编译为方法,因此您可以避免引用未初始化的值。可悲的是,我认为没有更好的解决方法。