Console.WriteLine () і необхідність такої кількості перевантажень аргументів?


87

Я переглядав документацію і помітив, що Console.WriteLine()метод мав кілька перевантажень. Зокрема, моя цікавість і часткова плутанина стосуються таких:

public static void WriteLine(string format, params object[] arg);
public static void WriteLine(string format, object arg0);
public static void WriteLine(string format, object arg0, object arg1);
public static void WriteLine(string format, object arg0, object arg1, object arg2);
public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3);

Це здається зайвим. У чому потреба інших чотирьох перевантажень поверх першої? Перший метод здатний зробити все, що можуть зробити інші методи. Чи існує занепокоєння щодо продуктивності, яку вони намагалися вирішити, надавши додаткові перевантаження, які обробляють до чотирьох аргументів (останній)? Чи достатньо великі накладні витрати на масив до чотирьох аргументів, щоб забезпечити потребу в цих перевантаженнях?

Відповіді:


102

Загалом, ви праві, що першого перевантаження може вистачити для інших перевантажень. Це не є суворою правдою, оскільки paramsключове слово не може використовуватися для непрямих випадків, таких як прив'язка групи методів. Наприклад

delegate void E(string format, object o1);
E e = Console.WriteLine;

Цей paramsвипадок не задовольнить цей випадок, він спрацює лише тоді, коли є саме це перевантаження

public static void WriteLine(string format, object arg0);

Це досить езотеричний випадок. Найважливішими причинами є наступні

  1. Не кожна мова CLI потрібна для підтримки paramsключового слова. Наявність перевантажень зменшує навантаження на ці мови, усуваючи необхідність створювати масив вручну для простого виклику WriteLine`
  2. Продуктивність. Виклик paramsперевантаження змушує абонента виділити масив, навіть якщо це неявно зроблено компілятором. Асигнування в .Net дешеві, але не безкоштовні. Такі дрібниці швидко складаються, особливо на таких загальновизнаних методах, як Console.WriteLine. Наявність інших перевантажень дозволяє у звичайних випадках уникнути такого розподілу

1
У своїй відповіді я думав про випадок групи методів, але я впевнений, що перетворення групи методів не було введено до С # 2.0, тоді як перевантаження WriteLine датується щонайменше 1.1.
jaket

@jaket Зручний синтаксис був доданий в C # 2.0. Але той самий момент застосовується, якщо ви використовуєте явний текст new E(Console.WriteLine)на C # 1.
CodesInChaos 07.03.14

5
Чи помітно виділення масиву, наскільки повільним є Console.WriteLine?
Брайан Ботчер

3
@insta проблема не в швидкості, а в накопиченні розподілів. GC дешевий, не безкоштовний, і в складних додатках GC часто є домінуючим фактором продуктивності. Зупинення загальних джерел непотрібного розподілу є важливим для ефективності
ДжаредПар

38

Перевантаження для зручності програм C ++ / CLI, де ключове слово params не існує.


1
Це чудова відповідь на чудове запитання, також IMHO.
Уве Кейм,

1
Ааа ... це насправді має багато сенсу. Ганьба мені, C ++ була моєю першою мовою. :)
BK

3
основи починаються з першої мови, розумний відповідь приятель
dbw

4

Думаю, ви всі, хлопці, забуваєте, що параметри були введені в C # 2.0. Отже, перевантаження також існують із .NET 1.1, коли ключове слово params цього не робило.


Джекет згадував про це.
BK

Прочитайте його коментар щодо відповіді ДжаредПара. Це одна з причин, чому він не включив пояснення до своєї відповіді.
BK

@Noobacode, це правда, що він це зробив, але це висновок (як я це читав). Я даю прихильність (за мінімум, що це варте) тут Алану, бо він заявив це в більш прямому садибі.
Франк V

1
З цього посилання params ключове слово існує і в .Net 1.1 також
Sriram Sakthivel

1

Я думаю , що питання , який задають вже має хороші і пояснювальні відповіді від JaredPar і jaket , але одне очко , що я думаю , що може мати відношення теж,

Я думаю, що простота використання та свобода для користувачів використовувати будь-яку з перерахованих вище функцій відповідно до вимог, отже, там є набагато зручніше, аніж нав'язувати їх для створення масиву, коли вони справді цього не вимагають.

Я думаю, що колишні часи, коли я почав вивчати C #, я майже не використовував масиви, і використання масивів було для мене складною задачею, призначити його, а потім ініціалізувати їх належними значеннями, було справді складним і трудомістким ...


3
Але ідея paramsполягає в тому, що ви можете або передати масив, або явно записати всі аргументи. такий метод, як void do(params object[])можна викликати за допомогою do(new object[] {"some", "stuff"}або do("some", "stuff"). Я не думаю, що ваша думка тут точно застосовна.
Кролтан 07.03.14

2
@Kroltan, але чи можете ви сказати, скільки початківців насправді знають значення paramsі знають, чи paramsє, тоді ви можете передавати змінні, розділені комами.
dbw

1
@Kroltan Я теж довго не знав, paramsяк це може бути, і в розділі довідки, що відображається у Visual Studion, якщо я отримаю array []як аргумент, я подумаю те саме, щоб надати масив як аргумент ....
dbw

-3

Це насправді не стосується продуктивності як такої. Однак збільшення корисності є вагомою причиною цього.

Наведений нижче код дасть вам невелике розуміння.

public class TipCalculator {
    private const double tipRate = 0.18;
    public static int Main(string[] args) {
        double billTotal;
        if (args.Length == 0) {
            Console.WriteLine("usage: TIPCALC total");
            return 1;
        }
        else {
            try {
                billTotal = Double.Parse(args[0]);
            }
            catch(FormatException) {
                Console.WriteLine("usage: TIPCALC total");
                return 1;
            }
            double tip = billTotal * tipRate;
            Console.WriteLine();
            Console.WriteLine("Bill total:\t{0,8:c}", billTotal);
            Console.WriteLine("Tip total/rate:\t{0,8:c} ({1:p1})", tip, tipRate);
            Console.WriteLine(("").PadRight(24, '-'));
            Console.WriteLine("Grand total:\t{0,8:c}", billTotal + tip);
            return 0;
        }
    }
}

Будь ласка, зверніться за посиланням: http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx для отримання додаткової інформації.


9
Як це збільшує зручність користування? Перший метод може робити точно те саме, що й інші чотири. Ви посилаєтесь на мене до документації, а я щойно сказав, що переглядаю документацію. Я знаю, для чого використовується цей метод і як його використовувати (я в С # ніяк не новачок). Але чому потрібні додаткові перевантаження поверх першого.
BK

Я думаю, що він має на увазі, що лише передаючи один параметр, немає сенсу створювати масив для його утримання та передавати його методу - чому б просто не передати один параметр? Це було б моєю причиною зробити щось подібне
KingTravisG 07.03.14

@ SCassidy1986: Ви не створюєте масив, коли це метод params, якщо ви цього не хочете. Компілятор зробить його автоматично. У цьому полягає і параметри, і це питання.
Magus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.