友元程序集(C# 编程指南)
更新:2007 年 11 月
可以从一个程序集访问另一个程序集中的内部类型或内部成员。
备注
友元程序集功能用于访问内部成员;私有类型和私有成员仍然不可访问。
若要使程序集(程序集 B)能够访问另一个程序集(程序集 A)的内部类型和成员,应使用程序集 A 中的 InternalsVisibleToAttribute 属性。
说明: |
---|
在对将要访问另一个程序集(程序集 A)的内部类型或内部成员的程序集(程序集 B)进行编译时,必须用 /out 编译器选项显式指定输出文件的名称(.exe 或 .dll)(有关更多信息,请参见 /out)。这是必需的,因为当编译器将生成的程序集绑定到外部引用时,尚未为该程序集生成名称。 |
StrongNameIdentityPermission 类还提供共享类型的功能,其与友元程序集的区别如下:
StrongNameIdentityPermission 应用于单个类型,而友元程序集应用于整个程序集。
如果希望程序集 B 能够共享程序集 A 中的数百个类型,则必须使用 StrongNameIdentityPermission 修饰所有这些类型;而使用友元程序集时只需声明一次友元关系。
使用 StrongNameIdentityPermission 时,想要共享的类型必须声明为公共类型。使用友元程序集时,会将共享类型声明为内部类型。
有关如何生成可访问程序集中的非公共类型的 .netmodule 的信息,请参见 /moduleassemblyname。
示例
在此示例中,程序集使内部类型和内部成员对名为 called cs_friend_assemblies_2 的程序集可见。
// cs_friend_assemblies.cs
// compile with: /target:library
using System.Runtime.CompilerServices;
using System;
[assembly:InternalsVisibleTo("cs_friend_assemblies_2")]
// internal by default
class Class1
{
public void Test()
{
Console.WriteLine("Class1.Test");
}
}
// public type with internal member
public class Class2
{
internal void Test()
{
Console.WriteLine("Class2.Test");
}
}
在此示例中,程序集使用程序集 cs_friend_assemblies.dll 中的内部类型和内部成员。
注意,必须显式指定输出文件的名称 (/out:cs_friend_assemblies_2.exe)。
如果此程序集允许另一个程序集(程序集 C)访问它的内部类型和成员,则程序集 C 不会自动变成程序集 cs_friend_assemblies.dll 的友元。
// cs_friend_assemblies_2.cs
// compile with: /reference:cs_friend_assemblies.dll /out:cs_friend_assemblies_2.exe
public class M
{
static void Main()
{
// access an internal type
Class1 a = new Class1();
a.Test();
Class2 b = new Class2();
// access an internal member of a public type
b.Test();
}
}
Class1.Test
Class2.Test
此示例演示了如何使内部类型和成员对具有强名称的程序集可用。
若要生成 keyfile 并显示公钥,请使用下面的 sn.exe 命令序列(有关更多信息,请参见强名称工具 (Sn.exe)):
sn -k friend_assemblies.snk // 生成强名称密钥
sn -p friend_assemblies.snk key.publickey // 将公钥从 key.snk 提取到 key.publickey 中
sn -tp key.publickey // 显示存储在文件 key.publickey 中的公钥
用 /keyfile 将 keyfile 传递到编译器。
// cs_friend_assemblies_3.cs
// compile with: /target:library /keyfile:friend_assemblies.snk
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("cs_friend_assemblies_4, PublicKey=0024000004800000940000000602000000240000525341310004000001000100031d7b6f3abc16c7de526fd67ec2926fe68ed2f9901afbc5f1b6b428bf6cd9086021a0b38b76bc340dc6ab27b65e4a593fa0e60689ac98dd71a12248ca025751d135df7b98c5f9d09172f7b62dabdd302b2a1ae688731ff3fc7a6ab9e8cf39fb73c60667e1b071ef7da5838dc009ae0119a9cbff2c581fc0f2d966b77114b2c4")]
class Class1
{
public void Test()
{
System.Console.WriteLine("Class1.Test");
}
}
此示例演示如何使用对具有强名称的程序集可用的内部类型和成员。
// cs_friend_assemblies_4.cs
// compile with: /keyfile:friend_assemblies.snk /reference:cs_friend_assemblies_3.dll /out:cs_friend_assemblies_4.exe
public class M
{
static void Main()
{
Class1 a = new Class1();
a.Test();
}
}
Class1.Test