江南才子 发表于 2021-7-20 21:45:42

IL查看override

查看override的IL
Override示例
下面我们看一个Override的Examplenamespace MyCollection
{
    public class MyBase
    {
      public virtual string Meth1()
      {
            return "MyBase-Meth1";
      }
      public virtual string Meth2()
      {
            return "MyBase-Meth2";
      }
      public virtual string Meth3()
      {
            return "MyBase-Meth3";
      }
    }
    class MyDerived : MyBase
    {
      // 使用 override 关键字重写虚方法 Meth1:
      public override string Meth1()
      {
            return "MyDerived-Meth1";
      }
      // 使用 new 关键字显式隐藏
      // 虚方法 Meth2:
      public new string Meth2()
      {
            return "MyDerived-Meth2";
      }
      // 由于下面声明中没有指定任何关键字
      // 因此将发出一个警告来提醒程序员
      // 此方法隐藏了继承的成员 MyBase.Meth3():
      public string Meth3()
      {
            return "MyDerived-Meth3";
      }
    }
    public class VirtualExample
    {
      public static void Main()
      {
            MyDerived mD = new MyDerived();
            MyBase mB = (MyBase)mD;
            System.Console.WriteLine(mD.Meth1());
            System.Console.WriteLine(mD.Meth2());
            System.Console.WriteLine(mD.Meth3());
            System.Console.WriteLine("以上为类MyDerived的显示结果!\n");
            System.Console.WriteLine(mB.Meth1());
            System.Console.WriteLine(mB.Meth2());
            System.Console.WriteLine(mB.Meth3());
            System.Console.WriteLine("以上为MyBase的显示结果!\n");
            System.Console.WriteLine("按任意键退出...");
            System.Console.ReadLine();
      }
    }
}
运行结果

IL查看
双击查看Main方法

IL代码
.method public hidebysig static voidMain() cil managed
{
.entrypoint
// Code size       121 (0x79)
.maxstack1
.locals init ( class MyCollection.MyDerived mD,
          class MyCollection.MyBase mB)
IL_0000:nop
IL_0001:newobj   instance void MyCollection.MyDerived::.ctor()
IL_0006:stloc.0
IL_0007:ldloc.0
IL_0008:stloc.1
IL_0009:ldloc.0
IL_000a:callvirt   instance string MyCollection.MyBase::Meth1()//调用的是MyBase的Meth1()
IL_000f:call       void System.Console::WriteLine(string)
IL_0014:nop
IL_0015:ldloc.0
IL_0016:callvirt   instance string MyCollection.MyDerived::Meth2()
IL_001b:call       void System.Console::WriteLine(string)
IL_0020:nop
IL_0021:ldloc.0
IL_0022:callvirt   instance string MyCollection.MyDerived::Meth3()
IL_0027:call       void System.Console::WriteLine(string)
IL_002c:nop
IL_002d:ldstr      bytearray (E5 4E 0A 4E 3A 4E 7B 7C 4D 00 79 00 44 00 65 00   // .N.N:N{|M.y.D.e.
                                  72 00 69 00 76 00 65 00 64 00 84 76 3E 66 3A 79   // r.i.v.e.d..v>f:y
                                  D3 7E 9C 67 01 FF 0A 00 )                         // .~.g....
IL_0032:call       void System.Console::WriteLine(string)
IL_0037:nop
IL_0038:ldloc.1
IL_0039:callvirt   instance string MyCollection.MyBase::Meth1()//这里一样调用的是MyBase的Meth1()
IL_003e:call       void System.Console::WriteLine(string)
IL_0043:nop
IL_0044:ldloc.1
IL_0045:callvirt   instance string MyCollection.MyBase::Meth2()
IL_004a:call       void System.Console::WriteLine(string)
IL_004f:nop
IL_0050:ldloc.1
IL_0051:callvirt   instance string MyCollection.MyBase::Meth3()
IL_0056:call       void System.Console::WriteLine(string)
IL_005b:nop
IL_005c:ldstr      bytearray (E5 4E 0A 4E 3A 4E 4D 00 79 00 42 00 61 00 73 00   // .N.N:NM.y.B.a.s.
                                  65 00 84 76 3E 66 3A 79 D3 7E 9C 67 01 FF 0A 00 ) // e..v>f:y.~.g....
IL_0061:call       void System.Console::WriteLine(string)
IL_0066:nop
IL_0067:ldstr      bytearray (09 63 FB 4E 0F 61 2E 95 00 90 FA 51 2E 00 2E 00   // .c.N.a.....Q....
                                  2E 00 )                                           // ..
IL_006c:call       void System.Console::WriteLine(string)
IL_0071:nop
IL_0072:call       string System.Console::ReadLine()
IL_0077:pop
IL_0078:ret

} // end of method VirtualExample::Main
IL解析
我们先回头看看源程序处的main内部的“System.Console.WriteLine(mD.Meth1());”语句对应上面的 IL_000a:callvirt   instance string MyCollection.MyBase::Meth1() 和 IL_0039:callvirt   instance string MyCollection.MyBase::Meth1()处的一模一样,原来它执行的是MyBase类的Meth1虚方法。而Meth1方法已经在 MyDerived类中重写了,所以这两个类的对应的方法1在本质说上都一样了。
通过看这个例子,我们能更加深入地理解override的功能了。看来ILdasm的确厉害,与其你想半天不如调IL代码看看,很多问题就会迎刃而解了,拨云见日啊!


文档来源:51CTO技术博客https://blog.51cto.com/zhaoqingqing/3146350
页: [1]
查看完整版本: IL查看override