2012-01-28 34 views
5

私はスタックオーバーフローのnewbyですので、私に簡単に行け!私は深くC#を読んでいますが、私はカバーされているとは思わないシナリオを見つけました。ウェブをすばやく検索しても、結果は失われませんでした。ジェネリックメソッドの型引数の型推論

は、私は、次のオーバーロードされたメソッドを定義すると言う:

void AreEqual<T>(T expected, T actual) 

void AreEqual(object expected, object actual) 

私は型引数を指定せずにAreEqual()を呼び出す場合:

AreEqual("Hello", "Hello") 

が呼び出されたメソッドのジェネリックか非ジェネリック版ですか?ジェネリックメソッドは、タイプ引数が推論されて呼び出されるか、またはメソッド引数が暗黙的にキャストされて非ジェネリックメソッドが呼び出されてSystem.Objectにキャストされていますか?

私の質問がはっきりしていることを願っています。アドバイスを事前に感謝します。

+5

これを確認する簡単なコードを書くことができます。 –

+1

http://blogs.msdn.com/b/ericlippert/archive/2009/07/30/generics-are-not-templates.aspx –

+0

@Mitch Wheat - 本当ですが、私は最初の投稿をしなくてもいいです。そして、他の人がここで答えを見るのに便利です。 – zekesteer

答えて

5

ジェネリックは、関数AreEqual(string, string)を生成できます。これはAreEqual(object, object)より近い一致であるため、汎用関数が選択されます。

興味深いことに、コンパイラは制約違反エラーが発生しても、この汎用関数を選択します。この例では

ルック:

using System.Diagnostics; 

namespace ConsoleSandbox 
{ 
    interface IBar 
    { 
    } 

    class Program 
    { 
     static void Foo<T>(T obj1) where T: IBar 
     { 
      Trace.WriteLine("Inside Foo<T>"); 
     } 


     static void Foo(object obj) 
     { 
      Trace.WriteLine("Inside Foo Object"); 
     } 

     static void Main(string[] args) 
     { 

      Foo("Hello"); 
     } 
    } 
} 

でもここでは、非ジェネリック版を超える一般的なバージョンを選択します。そして、あなたはこのエラーを取得する:

The type 'string' cannot be used as type parameter 'T' in the generic type or method 'ConsoleSandbox.Program.Foo(T)'. There is no implicit reference conversion from 'string' to 'ConsoleSandbox.IBar'.

しかし、あなたは機能Foo(string obj1)を追加する場合、それは動作します。

+0

偉大な答え、ありがとう!良い例ですが、私は確かにそれを試してみました:-) – zekesteer

+0

オーバーロードの解決は.NETフレームワークではなく、C#コンパイラによって行われることに注意してください。 – phoog

+0

@phoog - ありがとう、私は文言を変更しました –