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

时间:2017-10-05 08:55:12

标签: f# private cil internalsvisibleto

来自the F# 4.0 spec [PDF]

  

所有非公共实体的CLI编译形式为namespace MyNamespace.Foo module Bar = module Baz = let private myFun ...

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

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

在主项目的``AssemblyInfo.fs`中我有

myFun

(我已经仔细检查了这个名字。)

但是,在测试程序集(也是F#)中,引用The value 'myFun' is not accessible from this code location.时出现错误private如果从{{1}的定义中删除myFun,一切正常}。

奇怪的是,即使没有myFun,我也可以从C#项目调用私有InternalsVisibleTo

为什么在myFun实体编译为private且我在主程序集上指定internal时,无法从测试程序集访问私有InternalsVisibleTo

1 个答案:

答案 0 :(得分:2)

我认为语言级别和已编译的代码级别之间存在差异。

  • 在语言级别,private表现为私有,因此您只能在模块中调用该函数。如果您将绑定标记为internal,它将表现为内部,并且您可以从同一个程序集中调用它。

  • 在编译的代码级别,private编译为internal,可能是因为您可以使用闭包和序列表达式之类的东西,但F#编译器知道这只是一个编译工件

我没有试过这个,但是我想如果你从C#引用程序集那么它会表现为internal,因为C#编译器不理解F#编译器放入的特殊元数据标记let绑定。