Ответ 1
Приятно найти!
Это поведение undefined?
Нет. Это поведенческое поведение. Странный дизайн, но по дизайну.
Это зависит от версии .Net framework/Mono версии?
Нет. Все версии С# имеют такое поведение.
Это следствие столкновения некоторых интересных правил С#.
Первое соответствующее правило: метод с массивом params может быть вызван либо в "нормальной", либо в "расширенной" форме. Нормальная форма как будто не было "параметров". Расширенная форма принимает параметры и связывает их с массивом, который автоматически генерируется. Если применяются обе формы, то нормальная форма выигрывает над расширенной формой.
Теперь это, возможно, кажется разумным; если у вас есть массив объектов в руке, вероятность хорошая, что вы хотите передать массив объектов, а не массив, содержащий массив объектов.
Второе релевантное правило состоит в том, что С# допускает небезопасную ковариацию массива, когда тип элемента является ссылочным типом. То есть массив строк может быть преобразован в массив объектов неявно. Вы заметите, что это имеет два значения. Во-первых, это означает, что когда у вас есть массив объектов, это может быть массив строк, поэтому, например, черепаха в этот массив объектов может вызвать ошибку типа. Это очень удивительно! Вы ожидаете, что каждый массив объектов может принимать любой объект, но это не так в С#. Некоторые массивы объектов лежат.
Вторая проблема заключается в следующем: поскольку включение этой черепахи в то, что на самом деле представляет собой массив строк, должно бросаться, это означает, что каждый раз, когда вы помещаете что-то в массив базового типа, среда выполнения должна проверять, что типы проверяют. Таким образом, массивные записи на С# накладываются на дорогостоящие записи при каждой записи, так что исчезающее незначительное меньшинство плохой записи может быть обнаружено.
Это беспорядок, и именно поэтому небезопасная ковариация массивов покрывает мой список несчастливых функций С#.
Сочетание этих двух правил объясняет ваши наблюдения. Массив строк преобразуется в массив объектов, и поэтому метод применим в нормальной форме.
Для массива ints, ну, ковариация не применяется к типам значений. Таким образом, массив ints не конвертируется в массив объектов, поэтому метод не применим в его нормальной форме. Но массив ints является объектом, поэтому он применим в расширенной форме.
См. также:
Ваш вопрос, возможно, является дубликатом:
Есть ли способ отделить myFunc (1, 2, 3) от myFunc (new int [] {1, 2, 3})?