Смутно, почему этот код С# компилируется, в то время как аналогичный код не
Возьмем следующий метод расширения:
static class Extensions
{
public static bool In<T>(this T t, params T[] values)
{
return false;
}
}
Мне любопытно, почему этот код компилируется и запускается:
var x = new Object();
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);
Внутри In
, values
является Object[]
, как будто List<int>
преобразуется "на лету" в массив. Мне кажется, что params T[]
не соответствует IEnumerable<int>
, поэтому я удивлен, что это даже работает.
Теперь этот код:
var x = 5;
IEnumerable<int> p = new List<int> { 1, 2, 3 };
var t2 = x.In(p);
Не запускается и не генерирует ошибку компилятора:
Ошибка 2 Аргумент 2: невозможно преобразовать из 'System.Collections.Generic.IEnumerable' to 'int []'
Это то, чего я ожидаю от первого на самом деле. Может кто-нибудь объяснить, что здесь происходит? Спасибо!
Ответы
Ответ 1
Тип вывода преобразует ваш первый вызов в
In<object>(x, p);
Параметры этого замкнутого обобщенного метода object, params object[]
.
Поэтому передача p
неявно преобразует его в object
, который становится единственным элементом массива params.
Второй вызов выводится (из-за первого параметра) на
In<int>(x, p);
Здесь второй параметр может быть либо int[]
(передача массива напрямую), либо серия int
(через params
).
Поскольку IEnumerable<int>
не является ни одним из них, вы получаете сообщение об ошибке.