Подтвердить что ты не робот

Смутно, почему этот код С# компилируется, в то время как аналогичный код не

Возьмем следующий метод расширения:

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 []'

Это то, чего я ожидаю от первого на самом деле. Может кто-нибудь объяснить, что здесь происходит? Спасибо!

4b9b3361

Ответ 1

Тип вывода преобразует ваш первый вызов в

In<object>(x, p);

Параметры этого замкнутого обобщенного метода object, params object[].
Поэтому передача p неявно преобразует его в object, который становится единственным элементом массива params.

Второй вызов выводится (из-за первого параметра) на

In<int>(x, p);

Здесь второй параметр может быть либо int[] (передача массива напрямую), либо серия int (через params).
Поскольку IEnumerable<int> не является ни одним из них, вы получаете сообщение об ошибке.