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

标签 f# private cil internalsvisibleto

来自 the F# 4.0 spec [PDF] :

The CLI compiled form of all non-public entities is internal.

在我的主项目中我定义了一个函数

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

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

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

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

但是,在测试程序集(也是 F#)中,我在引用 myFun 时遇到错误,提示 无法从此代码位置访问值“myFun”。如果我从 myFun 的定义中删除 private 就可以正常工作。

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

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

最佳答案

我觉得语言层面和编译代码层面是有区别的。

  • 在语言级别,private 的行为是私有(private)的,因此您只能调用模块内的函数。如果您将绑定(bind)标记为 internal,它将表现为内部的,您将能够从同一个程序集中调用它。

  • 在编译代码级别,private 被编译为 internal,大概这样您就可以使用诸如闭包和序列表达式之类的东西,但是 F# 编译器知道这只是一个编译神器。

我没有尝试过,但我猜想如果您从 C# 引用程序集,那么它的行为将与 internal 相同,因为 C# 编译器不理解 F# 编译器放置的特殊元数据in 来标记 let 绑定(bind)。​​

关于f# - 如果 F# 中的私有(private)实体编译为内部,为什么 InternalsVisibleTo 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46581532/

相关文章:

f# - 摆脱 F# 中的 "pyramid of doom"

php - 从 openssl_pkey_get_private() 检索原始私钥

api - Windows Phone 8 - 私有(private) API?

c# - 如何在运行时删除 Emit IL 的最后几段

f# - 如何使用 F# 为属性声明私有(private) setter

c# - 函数式编程和解耦

arrays - 具有 O(1) 查找和 O(1) 切片的 F# 数组

c# - 自动实现属性的支持字段的可访问性是什么?

c# - 在 C# 中获取 'ldftn' 函数指针

C#结合MSIL——JIT跳过验证