2011-07-13 15 views
3

、ボクシングは(ジェネリック<タイプ>の.printで)発生します。奇妙な一般的な動作は、次のコードで

using System; 

namespace Test 
{ 
    static class Program 
    { 
     static void Main() 
     { 
      Generic<string> generic = new Generic<string>("test"); 
      generic.Print(); 
     } 
    } 

    class Generic<Type> 
    { 
     Type value; 

     public Generic(Type value) 
     { 
      this.value = value; 
     } 

     public void Print() 
     { 
      Console.WriteLine(value); 
     } 
    } 
} 

ILSpy出力:

.method public hidebysig 
    instance void Print() cil managed 
{ 
    // Method begins at RVA 0x207d 
    // Code size 17 (0x11) 
    .maxstack 8 

    IL_0000: ldarg.0 
    IL_0001: ldfld !0 class Test.Generic`1<!Type>::'value' 
    IL_0006: box !Type 
    IL_000b: call void [mscorlib]System.Console::WriteLine(object) 
    IL_0010: ret 
} // end of method Generic`1::Print 

それはボクシングと呼び出しだConsole.WriteLineを(オブジェクト) 。私は単純にConsole.WriteLine(string)を呼び出すと仮定しました。ここで何が起こっているのですか?

+0

コードの再利用のように見えます。 –

+3

Fyiの場合、ジェネリックパラメータ 'Type'は' System.Type'と競合する可能性があるので、それは悪い習慣です。 –

答えて

1

そのこれは、その呼び出しの最も適切なオーバーロードです。コンパイラが提供する型情報に基づいて、適切なオーバーロードを選択する必要があり、このような状況でのみ適切なものはobject過負荷である -

オーバーロードの解決は、コンパイル時で行われていることを覚えておいてください。

このことを理解するには、Mainメソッドを無視して、Genericクラスが異なるアセンブリに含まれているケースを検討してください。コンパイラはオーバーロードを選択する必要があり、Typeはキャストまたはボックス化してobjectにすることしかできません。ちょうどであるため、string型パラメーターでこのクラスを使用するアセンブリ内の他の場所では、Genericのコンパイル方法には影響しません。

またConsole.WriteLineobjectを受け入れる過負荷を持っていなかった場合に何が起こるかを検討 - (別の過負荷が適していますでしょうTypeに制限はありませんよう)この場合には方法は、単純にコンパイルされないでしょう。

+0

ありがとう。あなたの答えは私の質問の1つの部分を解決し、Jon Skeetの答えはもう一方を解決しましたが、受け入れられる答えは1つしか選択できません。あなたの答えは私が少し気にした部分に対処するので、私はあなたを選んだ。しかし、すべての回答が役に立ちました。 – Tom

0

再利用コードのようです。

あなたはそれをしないように強制することができます。

public void Print<Type>() 
{ 
    Console.WriteLine(value); 
} 
7

いいえ、実際には表示されません。 box命令のECMA-335の説明から:

typeTokは、参照型である場合、ボックス命令はOBJとしてヴァル不変の戻りを行います。

つまり、boxは参照型で呼び出すと無害です。

(JITがとにかく参照型と値型に対して個別のネイティブコードを生成するので、私は、これはちょうど完全参照型バージョンで除去されてしまうと思う。)のでConsole.WriteLineためobject過負荷を選択

+0

+1よし、私は4.1節でそれを見ています。 '返品します'、彼らはいくつかの証明読者が必要です:P – SwDevMan81