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