2009-03-31 6 views
3

Я попытался следующий код: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(); 
     } 
    } 

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

+0

Ваш код не скомпилирован - первые две сигнатуры метода идентичны. После удаления одного из них это нормально. Почему бы и нет? –

+0

Да, это была оригинальная версия, я просто хотел добавить новый метод здесь – Dutow

+0

ваш код отлично подходит после удаления базового класса (класс Program вместо класса Program: ProgParent). Я не знаю, где ваша проблема? – Vimvq1987

ответ

4

# язык Spec C говорит:

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

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

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

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

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

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

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

+1

ВНИМАНИЕ: Ваш код верен! :) – leppie

Смежные вопросы