相关文章推荐
彷徨的机器人  ·  stringvar转变成str ...·  2 周前    · 
留胡子的汤圆  ·  SharePoint 搜索 REST ...·  1 周前    · 
没有腹肌的开水瓶  ·  Exception in thread ...·  1 周前    · 
宽容的自行车  ·  hand detection using ...·  1 年前    · 
体贴的蘑菇  ·  linux - 折腾 Debian ...·  1 年前    · 
帅气的鼠标  ·  Pandas ...·  1 年前    · 
public ref class InternalsVisibleToAttribute sealed : Attribute
[System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)]
public sealed class InternalsVisibleToAttribute : Attribute
[<System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)>]
type InternalsVisibleToAttribute = class
    inherit Attribute
Public NotInheritable Class InternalsVisibleToAttribute
Inherits Attribute
Object
InternalsVisibleToAttribute

已签名程序集

以下示例使用 InternalsVisibleToAttribute 特性使已 internal 签名程序集中名为 AppendDirectorySeparator 的方法对另一个已签名程序集可见。 它定义一个 FileUtilities 包含内部 AppendDirectorySeparator 方法的类。 特性 InternalsVisibleToAttribute 应用于包含 类的 FileUtilities 程序集。 特性允许名为 的 Friend1 程序集访问此内部成员。

// The source code should be saved in a file named Example1.cs. It // can be compiled at the command line as follows: // csc /t:library /keyfile:<snkfilename> Assembly1.cs // The public key of the Friend1 file should be changed to the full // public key stored in your strong-named key file. using System; using System.IO; using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Friend1, PublicKey=002400000480000094" + "0000000602000000240000525341310004000" + "001000100bf8c25fcd44838d87e245ab35bf7" + "3ba2615707feea295709559b3de903fb95a93" + "3d2729967c3184a97d7b84c7547cd87e435b5" + "6bdf8621bcb62b59c00c88bd83aa62c4fcdd4" + "712da72eec2533dc00f8529c3a0bbb4103282" + "f0d894d5f34e9f0103c473dce9f4b457a5dee" + "fd8f920d8681ed6dfcb0a81e96bd9b176525a" + "26e0b3")] public class FileUtilities internal static string AppendDirectorySeparator(string dir) if (! dir.Trim().EndsWith(Path.DirectorySeparatorChar.ToString())) return dir.Trim() + Path.DirectorySeparatorChar; return dir; ' The source code should be saved in a file named Example1.cs. It ' can be compiled at the command line as follows: ' vbc Assembly1.vb /t:library /keyfile:<snkfilename> ' The public key of the Friend1 file should be changed to the full ' public key stored in your strong-named key file. Imports System.IO Imports System.Runtime.CompilerServices <Assembly:InternalsVisibleTo("Friend1, PublicKey=002400000480000094" + _ "0000000602000000240000525341310004000" + _ "001000100bf8c25fcd44838d87e245ab35bf7" + _ "3ba2615707feea295709559b3de903fb95a93" + _ "3d2729967c3184a97d7b84c7547cd87e435b5" + _ "6bdf8621bcb62b59c00c88bd83aa62c4fcdd4" + _ "712da72eec2533dc00f8529c3a0bbb4103282" + _ "f0d894d5f34e9f0103c473dce9f4b457a5dee" + _ "fd8f920d8681ed6dfcb0a81e96bd9b176525a" + _ "26e0b3")> Public Class FileUtilities Friend Shared Function AppendDirectorySeparator(dir As String) As String If Not dir.Trim().EndsWith(Path.DirectorySeparatorChar) Then Return dir.Trim() + Path.DirectorySeparatorChar Return dir End If End Function End Class

如果将以下示例编译为名为 Friend1 的强名称程序集,则 Example.Main 中的 Friend1 方法可以成功调用 FileUtilities.AppendDirectorySeparator 方法,尽管 该方法是程序集的内部 Assembly1 方法。 请注意,如果要从命令行使用 C# 进行编译,则必须使用 /out 编译器开关来确保在编译器绑定到外部引用时友元程序集的名称可用。

// The assembly that exposes its internal types to this assembly should be // named Assembly1.dll. // The public key of this assembly should correspond to the public key // specified in the class constructor of the InternalsVisibleTo attribute in the // Assembly1 assembly. #using <Assembly1.dll> as_friend using namespace System; void main() String^ dir = L"C:\\Program Files"; dir = FileUtilities::AppendDirectorySeparator(dir); Console::WriteLine(dir); // The example displays the following output: // C:\Program Files\ // The source code should be saved in a file named Friend1.cs. It // can be compiled at the command line as follows: // csc /r:Assembly1.dll /keyfile:<snkfilename> /out:Friend1.dll Friend1.cs // The public key of the Friend1 assembly should correspond to the public key // specified in the class constructor of the InternalsVisibleTo attribute in the // Assembly1 assembly. using System; public class Example public static void Main() string dir = @"C:\Program Files"; dir = FileUtilities.AppendDirectorySeparator(dir); Console.WriteLine(dir); // The example displays the following output: // C:\Program Files\ ' The source code should be saved in a file named Friend1.vb. It ' can be compiled at the command line as follows: ' vbc Friend1.vb /r:Assembly1.dll /keyfile:<snkfilename> ' The public key of the Friend1 assembly should correspond to the public key ' specified in the class constructor of the InternalsVisibleTo attribute in the ' Assembly1 assembly. Module Example Public Sub Main() Dim dir As String = "C:\Program Files" dir = FileUtilities.AppendDirectorySeparator(dir) Console.WriteLine(dir) End Sub End Module ' The example displays the following output: ' C:\Program Files\

无符号程序集

下面的示例使用 InternalsVisibleToAttribute 特性使 internal 未签名程序集的成员对另一个未签名程序集可见。 特性可确保 internal StringLib.IsFirstLetterUpperCase 名为 的程序集中的方法对名为 UtilityLib Friend2 的程序集中的代码可见。 下面是UtilityLib.dll的源代码:

using System; using System.Runtime.CompilerServices; [assembly: InternalsVisibleToAttribute("Friend2")] namespace Utilities.StringUtilities public class StringLib internal static bool IsFirstLetterUpperCase(String s) string first = s.Substring(0, 1); return first == first.ToUpper(); Imports System.Runtime.CompilerServices <assembly: InternalsVisibleTo("Friend2")> Namespace Utilities.StringUtilities Public Class StringLib Friend Shared Function IsFirstLetterUpperCase(s As String) As Boolean Dim first As String = s.Substring(0, 1) Return first = first.ToUpper() End Function End Class End Namespace

以下示例提供程序集的 Friend2 源代码。 请注意,如果要从命令行使用 C# 进行编译,则必须使用 /out 编译器开关来确保在编译器绑定到外部引用时友元程序集的名称可用。

#using <UtilityLib.dll> as_friend using namespace System; using namespace Utilities::StringUtilities; void main() String^ s = "The Sign of the Four"; Console::WriteLine(StringLib::IsFirstLetterUpperCase(s)); using System; using Utilities.StringUtilities; public class Example public static void Main() String s = "The Sign of the Four"; Console.WriteLine(StringLib.IsFirstLetterUpperCase(s)); Imports Utilities.StringUtilities Module Example Public Sub Main() Dim s As String = "The Sign of the Four" Console.WriteLine(StringLib.IsFirstLetterUpperCase(s)) End Sub End Module

通常,具有 internal C# 范围 Friend Visual Basic 中的作用域 的类型和成员仅在定义它们的程序集中可见。 在 Visual Basic) 中具有 protected internal 范围 ( Protected Friend 范围的类型和成员仅在其自己的程序集或从其包含类派生的类型中可见。 在 Visual Basic) 中具有范围 ( Private Protected 范围的类型和成员 private protected 在包含类或从当前程序集中的包含类派生的类型中可见

特性 InternalsVisibleToAttribute 使这些类型和成员也对指定程序集(称为友元程序集)中的类型可见。 这仅适用于 internal Visual Basic) Friend 中的 (、 protected internal Visual Basic) 中的 ( Protected Friend ,以及 private protected Visual Basic) 成员中的 ( Private Protected ,但不适用于 private 成员。

private protected 在 Visual Basic) 成员中 ( Private Protected 的情况下, 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 构造函数。

不要在 参数中包含 、 Version ProcessorArchitecture 字段的值 CultureInfo ;Visual Basic、C# 和 C++ 编译器将此视为编译器错误。 如果使用的编译器不将其视为错误 (如 IL 汇编程序 (ILAsm.exe) ) ,并且程序集具有强名称, MethodAccessException 则当指定的友元程序集首次访问包含 InternalsVisibleToAttribute 该特性的程序集时,将引发异常。

有关如何使用此属性的详细信息,请参阅 友元程序集 C++ 友元程序集

获取完整的公钥

可以使用 强名称工具 (Sn.exe) 从强名称密钥 (.snk) 文件中检索完整的公钥。 为此,请执行以下步骤:

  • 将公钥从强命名密钥文件提取到单独的文件中:

    Sn -p snk_file outfile

  • 向控制台显示完整的公钥:

    Sn -tp outfile

  • 将完整的公钥值复制并粘贴到源代码中。

    使用 C 编译友元程序集#

    如果使用 C# 编译器编译友元程序集,则必须使用 /out 编译器选项显式指定输出文件 (.exe 或.dll) 的名称。 这是必需的,因为编译器尚未为它在绑定到外部引用时而正在构建的程序集生成名称。 /out 编译器选项对于 Visual Basic 编译器是可选的,在使用 F# 编译器编译友元程序集时,不应使用相应的 -out -o 编译器选项。

    使用 C++ 编译友元程序集

    在 C++ 中,为了使由 属性启用 InternalsVisibleToAttribute 的内部成员可供友元程序集访问,必须在 as_friend C++ 指令中使用 属性。 有关详细信息,请参阅 友元程序集 (C++)

  •