zoukankan      html  css  js  c++  java
  • C#用Call代替CallVirt之后的测试用例

    一. C# 原始代码和直接结果

    测试 C# 代码:

    class Program
    {
        static void Main(string[] args)
        {
            A c1 = new C();
            c1.Foo();
    
            C c2 = new C();
            c2.Foo();
    
            Console.ReadKey();
        }
    }
    class A
    {
        public virtual void Foo()
        {
            Console.WriteLine("Call on A.Foo()");
        }
    }
    class B : A
    {
        public override void Foo()
        {
            Console.WriteLine("Call on B.Foo()");
        }
    }
    class C : B
    {
        public new void Foo()
        {
            Console.WriteLine("Call on C.Foo()");
        }
    }

    运行结果:

    二. IL程序编译的IL代码执行结果

    IL 代码:

    .assembly extern mscorlib
    {
        auto
    }
    .assembly MyTest{}
    .module MyTest.exe
    
    .class public A
    {
        .method public specialname void .ctor()
        {
            ldarg.0
            call instance void [mscorlib]System.Object::.ctor()
            ret
        }
        
        .method public newslot virtual void Foo()
        {
            ldstr "Call on A.Foo()"
            call void [mscorlib]System.Console::WriteLine(string)
            ret
        }
    }
    .class public B extends A
    {
        .method public specialname void .ctor()
        {
            ldarg.0
            call instance void A::.ctor()
            ret
        }
        
        .method public virtual void Foo()
        {
            ldstr "Call on B.Foo()"
            call void [mscorlib]System.Console::WriteLine(string)
            ret
        }
    }
    .class public C extends B
    {
        .method public specialname void .ctor()
        {
            ldarg.0
            call instance void B::.ctor()
            ret
        }
        
        .method public void Foo()
        {
            ldstr "Call on C.Foo()"
            call void [mscorlib]System.Console::WriteLine(string)
            ret
        }
    }
    .method public static void Main()
    {
        .entrypoint
        .locals (class A v_0,class C v_1)
        newobj instance void C::.ctor()
        stloc.0
        ldloc.0
        callvirt instance void A::Foo()
        newobj instance void C::.ctor()
        stloc.1
        ldloc.1
        callvirt instance void C::Foo()
        call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
        pop
        ret
    }

    运行结果:

     三. 用 Call 代替 CallVirt 的 IL

    IL 代码:

    .assembly extern mscorlib
    {
        auto
    }
    .assembly MyTest{}
    .module MyTest.exe
    
    .class public A
    {
        .method public specialname void .ctor()
        {
            ldarg.0
            call instance void [mscorlib]System.Object::.ctor()
            ret
        }
        
        .method public newslot virtual void Foo()
        {
            ldstr "Call on A.Foo()"
            call void [mscorlib]System.Console::WriteLine(string)
            ret
        }
    }
    .class public B extends A
    {
        .method public specialname void .ctor()
        {
            ldarg.0
            call instance void A::.ctor()
            ret
        }
        
        .method public virtual void Foo()
        {
            ldstr "Call on B.Foo()"
            call void [mscorlib]System.Console::WriteLine(string)
            ret
        }
    }
    .class public C extends B
    {
        .method public specialname void .ctor()
        {
            ldarg.0
            call instance void B::.ctor()
            ret
        }
        
        .method public void Foo()
        {
            ldstr "Call on C.Foo()"
            call void [mscorlib]System.Console::WriteLine(string)
            ret
        }
    }
    .method public static void Main()
    {
        .entrypoint
        .locals (class A v_0,class C v_1)
        newobj instance void C::.ctor()
        stloc.0
        ldloc.0
        call instance void A::Foo()
        newobj instance void C::.ctor()
        stloc.1
        ldloc.1
        call instance void C::Foo()
        call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
        pop
        ret
    }

    运行结果:

    四. 结论

    如果使用 Call 的话,它会简单粗暴的指针调用代码,即 A 中的 Foo 方法的代码进行执行。

  • 相关阅读:
    函数--第一类对象、闭包、
    递归
    局部变量 和 全局变量
    默认参数,不固定参数 *args,**kwargs
    函数基本语法及特性
    文件修改
    文件操作,重点,日常使用!!!
    集合
    重新写了一边三级菜单,加了一些自己的理解
    三级菜单
  • 原文地址:https://www.cnblogs.com/Jeffrey-Chou/p/11950728.html
Copyright © 2011-2022 走看看