Недавно я узнал, что вы можете создать какой-то метод с неограниченными параметрами, например:
SomeMethod(params int[] numbers);
но мой вопрос: в чем разница между этим и просто созданием метода, который получает список или массив?
SomeMethod(int[] numbers);
SomeMethod(List<int> numbers);
возможно, это как-то влияет на производительность? Я не совсем понимаю или не вижу, каким образом вы бы предпочли тот, с неограниченными параметрами.
Быстрый поиск в Google не помог, надеюсь, вы могли бы мне помочь.
params
также требуется, чтобы тип аргумента был массивом. Если вам нужно использовать коллекцию, отличную от массива, возможно, имеет смыслparams
вместо этого предоставить не аргумент.Console.Write
.Ответы:
Разница между
а также
это то, что М можно назвать так:
или вот так:
но N можно назвать только вторым способом, а не первым .
Влияние на производительность заключается в том, что независимо от того, вызываете ли вы
M
первым или вторым способом, вы получаете созданный массив. Создание массива влияет на производительность, поскольку требует времени и памяти. Помните, что влияние на производительность следует измерять относительно целей производительности; маловероятно, что стоимость создания дополнительного массива является определяющим фактором, определяющим разницу между успехом и провалом на рынке.Для автора кода, вызывающего метод, это полностью и полностью удобно; это просто короче и легче писать
вместо того чтобы писать
Это просто экономит несколько нажатий клавиш на стороне звонящего. Это все.
Несколько вопросов, которые вы не задавали, но, возможно, хотели бы знать ответ на:
Методы, позволяющие передавать переменное число аргументов на стороне вызывающей стороны, называются переменными . Методы Params - это то, как C # реализует переменные методы.
Столкнувшись с проблемой разрешения перегрузки, C # будет рассматривать как «нормальную», так и «расширенную» формы, и «нормальная» форма всегда выигрывает, если применимы обе. Например, рассмотрим это:
и у нас есть звонок
Есть две применимые возможности. В «нормальной» форме мы вызываем
P
и передаем нулевую ссылку для массива. В «развернутом» виде мы называемP(new object[] { null })
. В этом случае нормальная форма побеждает. Если у нас был вызов,P(null, null)
то обычная форма неприменима и расширенная форма выигрывает по умолчанию.Задача : предположим, у нас есть
var s = new[] { "hello" };
и звонокP(s);
. Опишите, что происходит на сайте вызова и почему. Вы можете быть удивлены!Задача : предположим, у нас есть и то
void P(object x){}
и другоеvoid P(params object[] x){}
. Что делаетP(null)
и почему?Задача : предположим, у нас есть и то
void M(string x){}
и другоеvoid M(params string[] x){}
. Что делаетM(null)
и почему? Чем это отличается от предыдущего случая?источник
P(null)
противP((object)null)
противP((object[])null)
- где я могу найти объяснение этой разницы? Такое ощущение, что уnull
него есть какой-то особый тип , который преобразует в массив, а не в object (P(null)
), но находит преобразование в строку или массив строк неоднозначным (M(null)
) ... что выглядит очень странно, ожидал бы, что он будет неоднозначным в обоих случаях или выберет версия с одним аргументом (чего нет). Но я полагаю, это больше связано с тем, чтобыparams
быть как-то универсальным , как универсальная ссылка (&&
) в шаблонах C ++, и, следовательно, лучше соответствовать (в Ch2, а не в Ch3).object[]
естьobject
, но не всеobject
естьobject[]
, поэтомуobject[]
конкретнее.string[]
естьstring
». На самом деле НЕТstring[]
естьstring
и НЕТstring
естьstring[]
, поэтомуstring
не является более конкретным или более общимstring[]
, и мы получаем ошибку двусмысленности при запросе выбора.object[]
ониobject
...object[]
более конкретны, поэтомуP(null)
речь идет о более конкретном массиве, thx, это то, чего мне не хватало. Здесь можно найти некоторые правила: docs.microsoft.com/en-us/dotnet/csharp/language-reference/…Просто сделал маленький прототип. Кажется, ответ таков:
params
это просто синтаксический сахар для передачи в массив. Это не совсем сюрприз. Я создал две версии одного и того же метода, где единственным отличием является ключевое слово «params». IL, сгенерированный для обоих, был идентичен, за исключением того, чтоSystem.ParamArrayAttribute
кparams
версии был применен a .Кроме того, IL, сгенерированный на сайте вызова, также был тем же, что и я, вызывающий метод с объявленным вручную,
new int[]
и вызывающий метод, используя толькоparams
аргументы.Таким образом, ответ, кажется, «удобство». Там, кажется, нет никакой разницы в производительности.
params
Вместо этого вы также можете вызвать функцию с массивом, так что это тоже не удивительно. Это сводится к тому, что потребителю вашего метода проще вызывать его с любым количеством параметров (напримерsomeMethod(1, 2, 3)
), чем всегда сначала создавать коллекцию (напримерsomeMethod(new List<int>() { 1, 2, 3 } )
).источник
Функция неограниченных параметров предлагает следующие преимущества во многих сценариях:
Вот пример, где опция неограниченных параметров - отличный выбор
Учтите, что приложение для отправки электронной почты должно быть построено.
Функция, отправляющая электронное письмо, должна иметь возможность обрабатывать одно или несколько значений для полей «Кому», «CC» и «BCC».
Если типы параметров фиксируются как массивы или списки для всех полей (To, CC, BCC), то вызывающая функция будет вынуждена иметь дело со всей сложностью определения 3-х массивов или списков для вызова функции отправителя электронной почты. ,
Даже если вызывающая сторона хочет отправить электронное письмо только на один адрес, функция отправителя электронной почты заставит вызывающую функцию определить и отправить 3 различных массива в качестве параметров.
Если функция отправителя электронной почты использует подход неограниченных параметров, то функция вызывающей стороны не должна иметь дело со всей сложностью.
Подход с неограниченными параметрами способствует лучшей производительности приложения во время выполнения, избегая создания массивов или списков там, где это не нужно.
источник
Из неисполнения , стиль точки зрения,
params
ключевое слово действительно приятно иметь , когда вы хотите отправить дополнительный список параметров.Лично я бы использовал,
params
когда мой код был что-то вродеПриятно то, что я могу использовать этот метод повсеместно, без необходимости каждый раз создавать массив или список.
Я бы использовал,
array
илиlist
когда я знаю, что я всегда буду передавать эту функцию набор данных, которые уже собраны какЯ вижу выгоду
params
в гибкости, которую он добавляет. Это может оказать относительно незначительное влияние на ваш код, но все же это хороший инструмент для работы.источник
Соглашение о вызовах отличается. Например ...
В первом случае вы можете передать в метод столько целых чисел, сколько отдельных параметров. Во втором случае вам нужно создать экземпляр списка и передать его.
источник