如果 F# 中的私有实体编译为内部实体,为什么 InternalsVisibleTo 不起作用?



来自 F# 4.0 规范 [PDF]:

所有非公共实体的 CLI 编译形式是internal

在我的主项目中,我有一个定义为

namespace MyNamespace.Foo
module Bar =
module Baz =
let private myFun ...

在主项目的"AssemblyInfo.fs"中,我有

[<assembly: InternalsVisibleTo("MyNamespace.Tests")>]

(我已经仔细检查了名称。

但是,在测试程序集(也是 F#)中,我在引用时出现错误myFunThe 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 绑定的特殊元数据。

最新更新