来自 F# 4.0 规范 [PDF]:
所有非公共实体的 CLI 编译形式是
internal
。
在我的主项目中,我有一个定义为
namespace MyNamespace.Foo
module Bar =
module Baz =
let private myFun ...
在主项目的"AssemblyInfo.fs"中,我有
[<assembly: InternalsVisibleTo("MyNamespace.Tests")>]
(我已经仔细检查了名称。
但是,在测试程序集(也是 F#)中,我在引用时出现错误myFun
说The value 'myFun' is not accessible from this code location.
如果我从myFun
的定义中删除private
一切正常。
奇怪的是,即使没有InternalsVisibleTo
,我也能够从 C# 项目调用私有myFun
。
为什么当private
实体编译为internal
并且我在主程序集上指定了InternalsVisibleTo
时,无法从测试程序集访问私有myFun
?
我认为语言级别和编译的代码级别之间存在差异。
-
在语言级别,
private
的行为是私有的,因此您只能在模块中调用函数。如果将绑定标记为internal
,它将表现为内部绑定,并且您将能够从同一程序集调用它。 -
在编译代码级别,
private
编译为internal
,大概是为了您可以使用闭包和序列表达式之类的东西,但 F# 编译器知道这只是一个编译工件。
我没有尝试过这个,但我猜如果你从 C# 引用程序集,那么它的行为会internal
,因为 C# 编译器不理解 F# 编译器放入以标记 let 绑定的特殊元数据。