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

  • 相关阅读:
    bat 批处理编写
    dos 命令
    反射
    反爬机制和破解方法汇总
    pandas
    谷歌历史浏览器下载
    python-----pip安装源选择(亲测有效)
    deepin 20.1 系统未安装pip
    python自带库-----os.path
    python 自带库---os库
  • 原文地址:https://www.cnblogs.com/Jeffrey-Chou/p/11950728.html
Copyright © 2011-2022 走看看