gpt4 book ai didi

.net - F# 实际上将私有(private)成员编译为 IL 中的内部成员。漏洞?

转载 作者:行者123 更新时间:2023-12-03 14:57:35 25 4
gpt4 key购买 nike

我一直认为 F# 中的访问控制关键字(publicprivateinternal)的工作方式与它们在 C# 中的工作方式相同。确实来自 MSDN 文档 Access Control (F#) :

  • public indicates that the entity can be accessed by all callers.
  • internal indicates that the entity can be accessed only from the same assembly.
  • private indicates that the entity can be accessed only from the enclosing type or module.


这似乎与我的假设非常一致,也与 SO 此处提供的有关该主题的多个答案一致。

然而,当我用 Reflector 探查编译后的代码时,我发现所有声明为私有(private)的成员实际上都编译为内部的(程序集可见性),这与文档不匹配。

为避免任何疑问,我创建了一个小测试来确认这一点。

F#代码:
// Make internals visible to other assemblies
[<assembly:InternalsVisibleTo("MyCSharpAssembly")>]


// OK. Expect: "internal static class PrivateModule" in C#
module private PrivateModule =

// FAIL. Expect: "private static void privateStaticMethod()" in C#
let private privateStaticMethod() = ignore()

// OK. Expect: "internal class InternalClass" in C#
type private InternalClass() =

// FAIL. Expect: "private int privateInstanceField" in C#
let privateInstanceField = 0

// FAIL. Expect: "private static int privateStaticField" in C#
static let privateStaticField = 0

// FAIL. Expect: "private int privateInstanceMethod()" in C#
let privateInstanceMethod() = privateInstanceField

// FAIL. Expect: "private in PrivateInstanceMember()" in C#
member private this.PrivateInstanceMember() = privateInstanceField

// OK. Expect: "internal int InternalInstanceMember" in C#
member internal this.InternalInstanceMember() = privateStaticField

我已经整理了一些 C# 代码,以确保我不是在想象事情。

C#测试代码 ,一切都会编译。
public class TestVisibility
{
// This is a demo to verify that the members are indeed
// internal (assembly) and can be accessed from C# if the
// F# assembly is compiled with [<assembly:InternalsVisibleTo("C# assembly")>]
public void Run()
{
// All of these compile.
PrivateModule.privateStaticMethod();

InternalClass x = new InternalClass();

int a = InternalClass.privateStaticField;
var b = x.InternalInstanceMember();
var c = x.PrivateInstanceMember();
var d = x.privateInstanceField;
var f = x.privateInstanceMethod();
}
}

我使用的是 VS2012,目标是 .NET 4.0,所有设置都是默认的。尝试了调试和 Release模式,结果相同。

问题 :根据设计,实际预期的行为是什么?它是一个错误吗?或者我做错了什么?

建议 :如果这是预期的行为,也许在某个地方的文档中明确提及这一点可能是个好主意?

最佳答案

来自 F# 3.0 specification : 所有非公开实体的 CLI 编译形式为 内部 .

关于.net - F# 实际上将私有(private)成员编译为 IL 中的内部成员。漏洞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18717501/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com