Я не знал, какое лучшее название выбрать для вопроса, поскольку не знаю, в чем проблема. Рассмотрим следующий небольшой код C#:
static void Main(string[] args)
{
F1(null);
}
public static void F1(int[] values)
{
F2(1, values?[0] as object ?? new object[0]);
F2(2, values?.Select(v => (object)v) ?? new object[0]);
F2(3, values?.Select(v => (object)v).ToArray() ?? new object[0]);
}
public static void F2(int idx, params object[] values)
{
Console.WriteLine($"count {idx}: '{values?.Count()}'");
}
Он выводит:
count 1: '1'
count 2: '1'
count 3: '0'
Почему первые 2 равны 1? Если я использую немедленное окно в Visual Studio, все следующее будет иметь значение null:
values?[0]
null
values?.Select(v => (object)v)
null
values?.Select(v => (object)v).ToArray()
null





Как вы, возможно, знаете, для параметра params типа object[] вы можете передать либо выражение типа object (которое неявно создает object[], и переданный вами object будет рассматриваться как элемент массива), либо выражение типа object[] (который будет передан методу «напрямую»).
object[] x = new object[0];
object y = new object();
F2(1, x); // values?.Count() is 0
F2(2, y); // values?.Count() is 1
Примечательно, что это зависит только от типа выражения во время компиляции (если только не происходит что-то dynamic). Следовательно, выражение типа object будет заключено в массив, даже если во время выполнения выражение оценивается как объект object[].
object z = new object[0];
F2(3, z); // values?.Count() is 1
Имея это в виду, должно быть понятно, почему ваш код ведет себя таким образом. Оба эти выражения относятся к типу object:
values?[0] as object ?? new object[0]
values?.Select(v => (object)v) ?? new object[0]
values?[0] as object имеет тип object, а values?.Select(v => (object)v) имеет тип IEnumerable<object>. Но правая часть ?? имеет тип object[]. Таким образом, в обоих случаях все выражение имеет тип object.
В случае
values?.Select(v => (object)v).ToArray() ?? new object[0]
values?.Select(v => (object)v).ToArray() имеет тип object[], того же типа, что и new object[0], поэтому все выражение относится к типу object[].
Потому что вы передаете новый объект, а не массив, который автоматически оборачивается в массив благодаря ключевому слову
params. Посмотрите, как параметр преобразуется в массив при понижении кода, если вставить его в Sharplab.io