C# и переменное количество параметров

Я попробовал следующий код:

class Program: ProgParent
    {

        public int Max(params int[] op)
        {
            return 0;
        }

        public int Max(int i, params int[] op)
        {
            return 1;
        }

        public int Max(int i, int j, params int[] op)
        {
            return 2;
        }

        public static void Main(string[] args)
        {
            System.Console.WriteLine((new Program()).Max(5, 6, 7, 8));
            System.Console.ReadKey();
        }
    }

Он выполняет и использует наиболее специфичную доступную функцию. Но компилятор не выдает предупреждений или ошибок по этому поводу. Зачем?

2 ответа

Решение

Спецификация языка C# гласит:

При выполнении разрешения перегрузки метод с массивом параметров может быть применим либо в его нормальной форме [то есть, передавая массив], либо в его расширенной форме [т.е. передавая переменное число параметров]. Расширенная форма метода доступна только в том случае, если обычная форма метода недоступна, и только если метод с такой же сигнатурой, что и расширенная форма, еще не объявлен в том же типе ".

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

Я думаю, что причины этого решения (вместо того, чтобы делать код, подобный вашему, нелегальным) включают в себя:

  • Если ваш метод имеет сигнатуру: void fn(params object[] p), вы хотите каким-то образом вызвать "нормальную форму" (передав объект []). Таким образом, компилятор должен обрабатывать неоднозначные случаи в любом случае.
  • Создание временного массива намного дороже, чем вызов метода, поэтому вы можете захотеть создать перегрузки без параметров с 1,2,3 параметрами, которые ведут себя одинаково, но являются более эффективными. (например, String.Format)

Игнорирование ошибок сборки (которые я опишу опечатками) - какое предупреждение вы ожидаете или хотите? Он находит соответствующую перегрузку и использует ее...

Строго говоря, я могу вызывать различные перегрузки - передавая массивы, но да, использование не совсем понятно.

Без многократных перегрузок с paramsэтот шаблон довольно сильно используется в таких вещах, как string.Concat и т. д. (что лежит в основе + для струн под капотом).

Другие вопросы по тегам