C#は、使用コールテストCallVirt後に交換しました

A. C#ソースコードと直接の結果

テストC#コード:

クラスプログラム
{ 
    静的 ボイドメイン(文字列[]引数)
    { 
        C1 = 新しいC(); 
        c1.Foo(); 

        C C2 = 新しいC(); 
        c2.Foo(); 

        Console.ReadKey(); 
    } 
} 
クラスA 
{ 
    パブリック 仮想 ボイドはFoo()
    { 
        Console.WriteLineを(" A.Foo()のコール" )。
    } 
} 
クラスB:A 
{ 
    パブリック オーバーライド ボイドFOO()
    { 
        Console.WriteLineを(" B.Foo()のコール" )。
    } 
} 
クラスC:B 
{ 
    公共 新しい ボイドはFoo()
    { 
        Console.WriteLineを(" C.Foo()のコール" )。
    } 
}

結果:

二つ。IL ILコードにコンパイル、実行結果

ILコード:

.assembly  のextern mscorlib 
{ 
    自動
} 
.assembly のMyTest {}
 .module MyTest.exe 

の.class  パブリックA 
{ 
    .method  公共 specialname  ボイド.ctor()
    { 
        ldarg.0の
         インスタンス ボイド[mscorlib] System.Objectの::。CTOR()
         RET 
    } 
    
    .method  公共 newslot 仮想 無効はFoo()
    { 
        ldstr  " A.Foo上のコール()" 
        を呼び出し 、ボイド([mscorlib] System.Console :: WriteLineメソッドをストリングRET 
    } 
} 
の.class  パブリック Bは延びAは
{ 
    .method  公共 specialname  ボイド.ctor()
    { 
        ldarg.0 
        コール インスタンス 空隙A ::。CTOR()
         RETを
    } 
    
    .method  パブリック 仮想 ボイドはFoo()
    { 
        ldstr  にコールB.Foo()" 
        を呼び出し 、ボイド [mscorlib] System.Console :: WriteLineメソッド(文字列RET 
    } 
} 
の.class パブリック Cは延びB 
{ 
    .method  公共 specialname  ボイド.ctor()
    { 
        ldarg.0の
         インスタンス 空隙Bを::。CTOR()
         RETが
    } 
    
    .method  公共 ボイドはFoo()
    { 
        ldstr  " C.Fooのコール()" 
        コール ボイド [mscorlib] System.Console :: WriteLineメソッド(文字列RET 
    } 
} 
.method  パブリック静的ボイドメインを()
{ 
    .entrypoint 
    .localsクラス A v_0、クラスCのV_1)
     NEWOBJ  インスタンス 空隙C ::。CTOR()
     stloc.0 
    ldloc.0 
    callvirt  インスタンス 空隙A ::フー()
     NEWOBJ  インスタンス 空隙C ::。CTOR()
     stloc.1 
    ldloc.1 
    callvirtの インスタンス 空隙C ::フー()
     コールの値型[mscorlib] System.ConsoleKeyInfo [mscorlib] System.Console :: ReadKey()
     ポップ
    RET 
}

結果:

 III。代わりにコールIL CallVirtの

ILコード:

.assembly  のextern mscorlib 
{ 
    自動
} 
.assembly のMyTest {}
 .module MyTest.exe 

の.class  パブリックA 
{ 
    .method  公共 specialname  ボイド.ctor()
    { 
        ldarg.0の
         インスタンス ボイド[mscorlib] System.Objectの::。CTOR()
         RET 
    } 
    
    .method  公共 newslot 仮想 無効はFoo()
    { 
        ldstr  " A.Foo上のコール()" 
        を呼び出し 、ボイド([mscorlib] System.Console :: WriteLineメソッドをストリングRET 
    } 
} 
の.class  パブリック Bは延びAは
{ 
    .method  公共 specialname  ボイド.ctor()
    { 
        ldarg.0 
        コール インスタンス 空隙A ::。CTOR()
         RETを
    } 
    
    .method  パブリック 仮想 ボイドはFoo()
    { 
        ldstr  にコールB.Foo()" 
        を呼び出し 、ボイド [mscorlib] System.Console :: WriteLineメソッド(文字列RET 
    } 
} 
の.class パブリック Cは延びB 
{ 
    .method  公共 specialname  ボイド.ctor()
    { 
        ldarg.0の
         インスタンス 空隙Bを::。CTOR()
         RETが
    } 
    
    .method  公共 ボイドはFoo()
    { 
        ldstr  " C.Fooのコール()" 
        コール ボイド [mscorlib] System.Console :: WriteLineメソッド(文字列RET 
    } 
} 
.method  パブリック静的ボイドメインを()
{ 
    .entrypoint 
    .localsクラス A v_0、クラスCのV_1)
     NEWOBJ  インスタンス 空隙C ::。CTOR()
     stloc.0の
    ldloc.0の
     インスタンス 空隙A ::フー()
     NEWOBJ  インスタンス 空隙C ::。CTOR()
     stloc.1 
    ldloc.1 
     インスタンス 空隙C ::フー()
     コールの値型[mscorlib] System.ConsoleKeyInfo [mscorlib] System.Console :: ReadKey()
     ポップ
    RET 
}

結果:

結論

使用される場合、それはコード、実行コード、すなわちFooのAメソッドを呼び出す簡単、粗ポインタになり、それを呼び出します。

おすすめ

転載: www.cnblogs.com/Jeffrey-Chou/p/11950728.html
おすすめ