Microsoft Intermediate Language(msil)
callvirt instance void MyApp.ITest::Test() nop ret } }
}
显式接口方法的实现,有几个关键词的应用,包括 private、virtual,以及 .override,当然还有方法名称的不同。该演示代码 C# 格式 namespace MyApp {
internal interface ITest {
void Test();
}
internal class MyClass : ITest {
public MyClass();
public override void Test();
void ITest.Test();
}
public class Program {
private static void Main(string[] args)
{
MyClass class2 = new MyClass();
class2.Test();
((ITest) class2).Test(); }
}
}
除了上述这些,我们还可以在接口中直接定义静态类型构造(.cctor)和静态方法。( 这回明白 CLR 和 C# 范围的区别了吧~~~~ .assembly extern mscorlib { auto } .assembly MyApp {} .module MyApp.exe .namespace MyApp {
.class interface ITest {
第 13 頁,共 29 頁
)
Microsoft Intermediate Language(msil)
.method public void Test() {}
.method static private specialname rtspecialname void .cctor() {
ldstr \
call void [mscorlib]System.Console::WriteLine(string) ret
}
.method public static void Do() {
ldstr \
call void [mscorlib]System.Console::WriteLine(string) ret }
}
.class MyClass implements MyApp.ITest {
.method public specialname rtspecialname void .ctor()
{
ldarg.0
call instance void [mscorlib]System.Object::.ctor() ret }
.method public virtual void Test() {
ldstr \
call void [mscorlib]System.Console::WriteLine(string) ret }
}
.class public auto ansi Program extends [mscorlib]System.Object {
.method private static void Main(string[] args)
{
.entrypoint
.locals init (class MyApp.ITest o) nop
newobj instance void MyApp.MyClass::.ctor()
stloc.0
ldloc.0
callvirt instance void MyApp.ITest::Test()
第 14 頁,共 29 頁
Microsoft Intermediate Language(msil)
nop
call void MyApp.ITest::Do() nop ret } } }
输出 Test... ITest.cctor ITest.Do
八、Enum
要定义一个枚举类型,我们必须声明一个拥有特定名称(value__)的实例字段来存储其底层类型,以及不少于一个的静态字段成员。枚举类型不能有方法、属性、事件。 .namespace MyApp {
.class enum Sex {
.field public specialname int32 value__
.field public static literal valuetype MyApp.Sex Femal = int32(1)
.field public static literal valuetype MyApp.Sex Male = int32(0) }
}
注意静态字段声明中的的几个关键词。上面这个枚举类型相当于 C# 中的 internal enum Sex {
Male,
Femal }
当然,我们也可以为枚举指定其他底层类型,诸如其他整数类型、布尔类型以及字符类型。 .class enum Sex {
.field public specialname int8 value__
.field public static literal valuetype MyApp.Sex Female = int8(1)
.field public static literal valuetype MyApp.Sex Male = int8(0)
}
相当于
internal enum Sex : sbyte {
Female = 1,
第 15 頁,共 29 頁
Microsoft Intermediate Language(msil)
Male = 0 }
可当你试图在 IL 中使用这个 Enum 时,会发现一个让人哭笑不得的异常被抛出。 .class public Program extends [mscorlib]System.Object {
.method static private void Main(string[] args) {
.entrypoint
ldsflda int32 MyApp.Sex::Female
call void [mscorlib]System.Console::WriteLine(int32) ret } } 输出
Unhandled Exception: System.MissingFieldException: Field not found: 'MyApp.Sex.Female'. at MyApp.Program.Main(String[] args)
原 因是 literal field 并不是一种 \真正\意义上的字段,它们是一种编译期常量
(compile-time constant),以常量值方式存储到元数据表中,JIT 并不会为它们分类内存空间(csc 等编译器会使用实际常量来替换代码中的枚举字段)。也就是说我们在 IL 定义一个枚举类型的作用是:
(1) 做成类库,供 C# / VB.NET 等语言调用。 (2) 用于反射元数据。
当我们试图用 ldsfld 载入枚举字段时,JIT Compiler 会抛出 MissingFieldException 异常,并终止任务执行。 九、Nested Type
在 IL 中我们可以在 classes、interface、value types 中创建嵌套类型,不过 Nested Type 的表达式语法有点古怪。
.class MyClass {
.class nested public MyClassSub { }
.field valuetype MyClass/MyClassSub o
}
相关规则:
(1) Nested type 对象不会拥有 Enclosing type 的实例引用(指针)。 (2) 创建 Enclosing type 实例时不会自动创建 Nested type 实例。 (3) Nested type 受 Enclosing type 访问权限限制。 使用演示:
第 16 頁,共 29 頁

