本文提供了此 API 参考文档的补充说明。
该 InternalsVisibleToAttribute 特性指定通常仅在当前程序集内可见的类型对指定的程序集可见。
通常,在 C# 中具有internal
作用域的类型和成员或在 Visual Basic 中具有Friend
作用域的类型和成员,仅在定义它们的程序集中可见。 作用域为 protected internal
的类型和成员(在 Visual Basic 中为作用域 Protected Friend
)仅对其所在程序集可见,或对从其包含类派生的类型可见。 具有 private protected
作用域的类型和成员(在 Visual Basic 中为 Private Protected
作用域)在包含类中或在当前程序集从包含类派生的类型中可见。
InternalsVisibleToAttribute 属性使得这些类型和成员也对指定程序集中的类型可见,这被称为友元程序集。 这仅适用于 internal
(Friend
在 Visual Basic 中)、 protected internal
(Protected Friend
在 Visual Basic 中)和 private protected
(Private Protected
在 Visual Basic 中)成员,但不适用于 private
这些成员。
注释
对于 private protected
(Private Protected
在 Visual Basic 中)成员,该 InternalsVisibleToAttribute 属性仅将访问权限扩展到从成员的 包含类 派生的类型。
属性在程序集级别应用。 这意味着它可以包含在源代码文件的开头,也可以包含在 Visual Studio 项目中的 AssemblyInfo 文件中。 可以使用该属性指定可以访问当前程序集的内部类型和成员的单个友元程序集。 可以通过两种方式定义多个友元程序集。 它们可以显示为单个程序集级属性,如以下示例所示。
[assembly:InternalsVisibleTo("Friend1a")]
[assembly:InternalsVisibleTo("Friend1b")]
<assembly:InternalsVisibleTo("Friend1a")>
<assembly:InternalsVisibleTo("Friend1b")>
它们还可以分别用 InternalsVisibleToAttribute 标记显示,但使用单一的 assembly
关键字,如以下示例所示。
[assembly:InternalsVisibleTo("Friend2a"),
InternalsVisibleTo("Friend2b")]
<Assembly:InternalsVisibleTo("Friend2a"), _
Assembly:InternalsVisibleTo("Friend2b")>
友元程序集由 InternalsVisibleToAttribute 构造函数标识。 当前程序集和友元程序集都必须未签名,或者两个程序集都必须使用强名称进行签名。
如果两个程序集都是无符号的,则 assemblyName
参数由未指定目录路径或文件扩展名的友元程序集的名称组成。
如果两个程序集都使用强名称进行签名, InternalsVisibleToAttribute 则构造函数的参数必须包含程序集的名称,而不包含其目录路径或文件扩展名,以及完整的公钥(而不是其公钥令牌)。 若要获取强名称程序集的完整公钥,请参阅本文后面的 “获取完整公钥 ”部分。 有关与强名称程序集一起使用 InternalsVisibleToAttribute 的详细信息,请参阅 InternalsVisibleToAttribute 构造函数。
不要在参数中包含CultureInfo、Version或ProcessorArchitecture字段的值,Visual Basic、C#和C++编译器将此视为编译器错误。 如果使用的编译器不将此视为错误(如 IL 汇编程序 (ILAsm.exe))并且程序集具有强名称,那么首次指定的友元程序集访问包含 MethodAccessException 属性的程序集时,将引发 InternalsVisibleToAttribute 异常。
有关如何使用此属性的详细信息,请参阅 Friend 程序集 和 C++友元程序集。
获取完整的公钥
可以使用 强名称工具(Sn.exe) 从强名称密钥(.snk)文件中检索完整的公钥。 为此,请执行以下步骤:
将公钥从强命名密钥文件提取到单独的文件中:
Sn -p <snk_file> <outfile>
向控制台显示完整的公钥:
Sn -tp <outfile>
将完整的公钥值复制并粘贴到源代码中。
使用 C# 编译友元程序集
如果使用 C# 编译器编译友元程序集,则必须使用 /out 编译器选项显式指定输出文件的名称(.exe 或 .dll)。 这是必需的,因为编译器尚未生成它在绑定到外部引用时正在生成的程序集的名称。 对于 Visual Basic 编译器, /out 编译器选项是可选的,在使用 F# 编译器编译友元程序集时,不应使用相应的 -out 或 -o 编译器选项。
使用 C++ 编译友元程序集
在 C++ 中,为了使由 InternalsVisibleToAttribute 属性启用的内部成员能被友元程序集访问,必须在 C++ 指令中使用 as_friend
属性。 有关详细信息,请参阅友元程序集(C++)。