• 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 方法的代码进行执行。

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    Jenkins安装部署项目
    通过jenkins构建服务,并发布服务,修改Jenkins以Root用户运行
    nohup和&后台运行,进程查看及终止
    Scala基础
    大数据体系概览Spark、Spark核心原理、架构原理、Spark特点
  • 原文地址:https://www.cnblogs.com/Jeffrey-Chou/p/11950728.html
Copyright © 2020-2023  润新知