Вывод типа для аргументов типа универсальных методов - PullRequest
5 голосов
/ 28 января 2012

Я новичок в Stack Overflow, поэтому, пожалуйста, будьте осторожны со мной!Я читаю C # в глубине, но я столкнулся с сценарием, который я не верю, что покрыт.Быстрый поиск в Интернете также не дал никаких результатов.

Скажем, я определяю следующие перегруженные методы:

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

void AreEqual(object expected, object actual)

Если я вызываю AreEqual() без указания аргумента типа:

AreEqual("Hello", "Hello")

Вызывается ли общая или неуниверсальная версия метода?Вызывается ли обобщенный метод с выводом аргумента типа или неуниверсальный метод вызывается с неявным приведением аргументов метода к System.Object?

Надеюсь, мой вопрос ясен.Заранее спасибо за любой совет.

1 Ответ

5 голосов
/ 28 января 2012

Обобщения могут генерировать функцию 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");
        }
    }
}

Даже ЗДЕСЬ он выберет универсальную версию над неуниверсальной версией. И тогда вы получите эту ошибку:

Тип 'string' нельзя использовать в качестве параметра типа 'T' в общем введите или метод 'ConsoleSandbox.Program.Foo (T)'. Здесь нет неявное преобразование ссылки из 'string' в 'ConsoleSandbox.IBar'.

Но если вы добавите функцию Foo(string obj1), она будет работать.

...