F#don'中的模块值;无法初始化。为什么?

F#don'中的模块值;无法初始化。为什么?,f#,module,F#,Module,我用F#时有一种奇怪的行为。 当我在模块中使用let绑定时,如果该值是从构造函数创建的,那么当在外部使用时,它是未初始化的。(我从C#使用ModuleName.s2或ModuleName.f()使用它) 这是正常的行为吗?提前谢谢 编辑: 为了调试,我选择将其编译为可执行文件。这可能是其他人指出的问题。在F#库中,模块通过静态构造函数初始化,静态构造函数确保在使用任何模块值之前进行初始化。相反,在F#可执行文件中,该初始化是在应用程序的入口点执行的。这意味着,如果另一个程序集引用了F#应用程序(

我用F#时有一种奇怪的行为。 当我在模块中使用let绑定时,如果该值是从构造函数创建的,那么当在外部使用时,它是未初始化的。(我从C#使用ModuleName.s2或ModuleName.f()使用它)

这是正常的行为吗?提前谢谢

编辑: 为了调试,我选择将其编译为可执行文件。这可能是其他人指出的问题。

在F#库中,模块通过静态构造函数初始化,静态构造函数确保在使用任何模块值之前进行初始化。相反,在F#可执行文件中,该初始化是在应用程序的入口点执行的。这意味着,如果另一个程序集引用了F#应用程序(不管另一个应用程序使用何种语言编写),则初始化代码将不会运行

更新

布赖恩指给我看,这表明这是预期的行为

一种解决方法似乎是提供一个明确的入口点,如下所示:

[<EntryPoint>]
let main _ =
    0
[]
让主=
0
然后,您可以从C#应用程序调用此main方法,以确保模块的内容已正确初始化

更新2


我误读了规范-实际上不需要从引用程序集调用显式入口点。它的存在将导致正确地进行初始化。

出于某种原因,
SomeModule.s2
被实现为一个(只读)属性,返回无法说出的静态字段
$程序的值。s2@9
。如果编译为应用程序,则该字段将在main方法中初始化。从C#代码中使用时,不会调用此方法,因此该字段不会初始化

如果编译为库,则代码是相同的,只是字段在
$Program
类的静态构造函数中初始化,因此从C#使用时应该可以工作


s1
总是起作用的原因是优化:F#编译器理解它是一个常量,并将
F()
实现为
“1”。出于好奇,等于(“某物”)

您的F#程序集是库还是可执行文件?@kvb,我只有在作为可执行文件编译时才会出现这种行为。@kvb,可执行文件。稍后我可能会将其更改为库,但可执行文件似乎更适合调试。非常感谢。我不知道库和可执行文件之间有区别。谢谢你的详细回答。@LLS-很乐意帮助。我做了一个小的修正-你不需要从另一个程序集调用入口点。这就是为什么我喜欢堆栈溢出,+1是这个非常有用的答案!我想知道为什么一切都是空的。我认为这与模块的某些部分没有正确初始化有关。F#3.1-我有一个明确的入口点,但仍然遇到这个问题。(我有一个引用.exe的单元测试项目。单元测试失败是因为不应该为null的东西为null。)@kvb-经过一些调试后,我发现我的问题是由完全不同的东西引起的/只是症状完全相同。所以F#做的一切都是对的,你对入口点的建议是有效的!(注:我验证了它仍然可以与.NET4.0、4.5、4.5.1和F#3.0和3.1一起使用)
[<EntryPoint>]
let main _ =
    0