2015-10-01 3 views
21

Почему общий метод называется, когда будут совпадать обе перегрузки?Какая перегрузка метода C# выбрана?

public static void method1(object obj) 
{ 
    Console.WriteLine("Object"); 
} 

public static void method1<T>(T t) 
{ 
    Console.WriteLine("Type T"); 
} 

public static void Main(String args[]) 
{ 
    method1("xyz"); //Will print "Type T"; 
} 

Здесь не должно быть конфликтов, не так ли?

+0

Похоже на [этот вопрос] (http://stackoverflow.com/questions/9017363/ambiguous-method-overloading) – adelphus

ответ

36

Перегрузки устраняются путем выбора наиболее конкретной перегрузки. В этом случае method1<string>(string) более конкретный, чем method1(object), так что выбрана перегрузка.

Подробнее ... section 7.4.2 of the C# specification.

Если вы хотите выбрать конкретную перегрузку, вы можете сделать это, явно задав параметры тем типам, которые вы хотите. Далее будем называть method1(object) перегрузки вместо родового один:

method1((object)"xyz"); 

Есть случаи, когда компилятор не будет знать, какой перегружать, чтобы выбрать, например:

void method2(string x, object y); 
void method2(object x, string y); 

method2("xyz", "abc"); 

В этом случае компилятор не знает, какую перегрузку выбрать, потому что ни перегрузка явно лучше, чем другая (она не знает, какая строка неявно опущена к объекту). Поэтому он испустит ошибку компилятора.

10

C# всегда будет выбирать наиболее подходящий метод.

При составлении

method1("xyz"); 

это будет выглядеть для всех методов с указанным именем, а затем пытаться соответствовать параметрам. Компилятор выбрать метод, который является наиболее конкретно, в этом случае он предпочел бы

method1(string s) 

над

method1<T>(T t) with T = string 

и, наконец,

method1(object o) 

Пожалуйста, обратите внимание @ отличный ответ Эрика в течение пример, когда компилятор не может решить.

+0

Он не ищет 'method1 (string s)' он смотрит на методы с тем же имя определяет наилучшее совпадение. – juharr

+0

@juharr Вы правы, позвольте мне немного почистить мой ответ – Vlad274

+0

Вам еще нужно удалить часть 'method1 (string s)'.Он предпочитает 'метод (T t)' over' method1 (object o) ' – juharr

2

Поскольку вы уже проходите в T как параметр, поэтому вам не нужно вводить код method1<string>("xyz");, вы можете просто пойти method1("xyz"); .Net уже знает, что это строка. Если бы у вас был метод1, тогда это была бы другая история.

Кроме того, поскольку method1(object obj) не принимает в строку в качестве параметра будет благоприятствовать обобщенную функцию первой, где он может сделать вывод T. Если вы должны были изменить method1(object obj) к method1(string obj) это будет благоприятствовать его первым, родовое.

+0

Ну, на самом деле это компилятор C#, который реализует общий тип вывод, p не имеет ничего общего с .net –

Смежные вопросы