5

私は Stack Overflow の初心者なので、気楽にやってください! C# in Depth を読んでいますが、カバーされていないと思われるシナリオに出くわしました。Web をすばやく検索しても結果は出ませんでした。

次のオーバーロードされたメソッドを定義するとします。

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

void AreEqual(object expected, object actual)

AreEqual()型引数を指定せずに呼び出した場合:

AreEqual("Hello", "Hello")

メソッドの汎用バージョンまたは非汎用バージョンが呼び出されているか? 型引数が推論された状態で呼び出されたジェネリック メソッドですか、それともメソッド引数が暗黙的に にキャストされた状態で呼び出された非ジェネリック メソッドSystem.Objectですか?

私の質問が明確であることを願っています。アドバイスをよろしくお願いします。

4

1 に答える 1

5

The generics can generate a function AreEqual(string, string). This is a closer match than AreEqual(object, object), so therefore the generic function is chosen.

Interestingly, the compiler will choose this generic function even if it results in a constraint violation error.

Look at this example:

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");
        }
    }
}

Even HERE it will choose the generic version over the non-generic version. And then you get this error:

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'.

But if you add a function Foo(string obj1) it will work.

于 2012-01-28T01:51:02.457 に答える