C#: ключевое слово params против списка

Каковы про / недостатки использования params ключевого слова против Списка, как введено к некоторой функции c#?

Главным образом, каковы исполнительные соображения и другая торговля offs.

33
задан Yaron Naveh 22 January 2010 в 01:29
поделиться

8 ответов

Ключевое слово параметров синтаксический сахар обрабатывается компилятором C #. Под капотом на самом деле он включает

void Foo(params object[] a) { ... }
Foo(1,2,"THREE");

в

void Foo(object[] a) { ... }
Foo(new object[] { 1, 2, "THREE" })

из Performance , как вы спрашиваете, параметры вызов просто быстрее, потому что это немного быстрее создать массив, чем это Создать список <>. Нет разницы производительности между двумя фрагментами выше.

36
ответ дан 27 November 2019 в 18:08
поделиться

Лично я использую params При написании функций, которые принимают ряд входов, предоставляемых другим программистом (например, String.format ), а Ienumerable При написании функций, которые принимают список элементов данных, предоставленные компьютером (например file.write ).

Последние последствия незначительны. Беспокойство о выступлении тривиальной вещи, подобной это , ровно , о том, о чем говорил Дональд Кнут, о котором говорил в знаменитой «преждевременной оптимизации, является корнем всех злых» цитата.

, который сказал, что, похоже, Асят, кажется, зацикливается на нем, поэтому здесь вы идете:

Результаты на 10 миллионов итераций:

params took 308 ms
list took 879 ms

Из этих результатов мы можем видеть, что массив параметров находится чуть более длиннее. Простой факт, что вы можете позвонить ни одному из этих вещей в десять миллионов раз , в течение второго означает, что вы полностью тратите свое время, беспокоясь об этом. Используйте все, что подходит для вашего кода лучшим.

Код для тестирования его (скомпилирован и запущен в режиме выпуска с использованием VS2008)

class Program
{
    const int COUNT = 10000000;

    static IEnumerable<string> m_value = null;

    static void ParamsMethod(params string[] args)
    { m_value = args; } // do something with it to stop the compiler just optimizing this method away

    static void ListMethod(List<string> args)
    { m_value = args; } // do SOMETHING with it to stop the compiler just optimizing this method away

    static void Main(string[] args)
    {
        var s = new Stopwatch();
        s.Start();
        for (int i = 0; i < COUNT; ++i)
            ParamsMethod("a", "b", "c");

        Console.WriteLine("params took {0} ms", s.ElapsedMilliseconds);

        s.Reset();
        s.Start();
        for (int i = 0; i < COUNT; ++i)
            ListMethod(new List<string> { "a", "b", "c" });

        Console.WriteLine("list took {0} ms", s.ElapsedMilliseconds);
    }
}
24
ответ дан 27 November 2019 в 18:08
поделиться

Ключевое слово params позволяет динамически передавать переменное количество аргументов функции, не беспокоясь об ошибках компилятора, как это:

public string PrefixFormatString(string p, string s, params object[] par)
{ 
    return p + string.Format(s, par);
}
...
PrefixFormatString("COM", "Output Error #{0} - Error = {1}", errNum, errStr);

, если вы передаете список, вы должны построить список до Вы можете пройти его в:

public string PrefixFormatString(string p, string s, List<object> par)
{ 
    return p + string.Format(s, par.ToArray());
}
...
List<object> l = new List<object>(new object[] { errNum, errStr });
PrefixFormatString("COM", "Output Error #{0} - Error = {1}", l);

, и он имеет тенденцию скрывать значение того, какие данные ожидают функции.

Обратите внимание, что это очень похоже на передачу простой переменной массива. Единственное отличие состоит в том, что компилятор исправит параметры в массиве для вас ... Я не на 100% уверен, но я думаю, что техническая разница - просто синтаксический сахар - в любом случае вы действительно проходите на массив чего-либо Введите параметр.

2
ответ дан 27 November 2019 в 18:08
поделиться

Ну с ключевым словом params вы можете вводить аргументы в метод, подобный это:

MethodName(1, 2, 3, 4);

, но со списком, вы бы сделали это так:

MethodName(new List<int> {1, 2, 3, 4});

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

// params
MethodName(1);

// List
MethodName(new List<int> {1});
1
ответ дан 27 November 2019 в 18:08
поделиться

Пармы - это языковая конструкция для функций, принимающих переменное количество параметров. Это похоже на Спецификатор ELIPSES - I.E. PrintF (CHAR * FMT, ...) . Язык поддерживает такую ​​операцию, может также использовать его, особенно если это облегчает чтение кода.

0
ответ дан 27 November 2019 в 18:08
поделиться

Основное отличие между ними, которые я вижу, состоит в том, что количество параметров, передаваемых в метод, устанавливается при компиляционном времени с использованием Params , в то время как с Список Это зависит от списка, передаваемого во время выполнения.

Независимо от того, следует ли исправлять количество аргументов, которые ваш метод должен быть вызван с временем компиляции, является Pro или Con, полностью зависит от вашего дизайна и намерения для него. Либо может быть выгодом в зависимости от того, что вы надеетесь достичь.

Пармы помогают на передней части читаемости, а также так близко к необязательному параметру, который вы собираетесь добраться до в C #. Я бы использовал только в режиме реализации , если мне нужно было потреблять неизвестное количество параметров в любой точке.

Отредактируйте: просто заметили вашу редактирование вопросов производительности. На этой теме я не уверен, хотя, если бы вы могли потенциально ожидать большое количество «параметров», используя список , тогда как Params имеет здравоохранение на нем должен быть закодирован.

0
ответ дан 27 November 2019 в 18:08
поделиться

Лично я бы пропустил слова. Я был укушен этим один или два раза. Как? Позволь мне объяснить.

Вы пишете общественный метод с этой подписью:

public static void LogInUser(string username, string password, params string[] options)

Вы тестируете его, он работает, это сделано ... и другое сборка / приложение вызывает вашу функцию.

Теперь, через месяц вы хотите изменить свою подпись, чтобы добавить роль пользователя:

public static void LogInUser(string username, string password, string role, params string[] options)

О, как все изменилось на что-либо, вызывая ваш метод.

LogInUser("z@z.com", "zz", "Admin", "rememberMe", "800x600");
0
ответ дан 27 November 2019 в 18:08
поделиться

Ну, Params позволяет более приятным синтаксисом при вызове его, но список (при условии, что вы имеете в виду Ilist <> ) более гибкий, потому что Различные классы могут реализовать интерфейс. Прохождение списка <> имеет смысл, только если вам нужно выполнить определенные операции в списке, которые не поддерживаются интерфейсом (например, Toarray () ).

2
ответ дан 27 November 2019 в 18:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: