Очистка потока управления при обработке аргументов командной строки [C #] - PullRequest
4 голосов
/ 17 февраля 2010

Я имею дело с программой, которая выполняет множество ветвлений if ... else на основе аргументов командной строки. Это в C #, но я уверен, что это применимо к Java, C ++ и т. Д. Вот общая схема:

if (args.Length == 0)
{
  //do something
}

if (args.Length > 0 && args.Length < 2)
    {
        Console.WriteLine("Only one argument specified. Need two arguments");
        return 0;

    }
            else if (args.Length > 0 && args.Length >= 2)
            {
                //Process file - Argument 1
                if(args[0].Trim() == PROCESS_OPTION_ONE
                    || args[0].Trim() == PROCESS_OPTION_TWO)
                {
                    //Process file - Argument 2
                    if(args[1].Trim() == PROCESS_CUSTOMER
                        || args[1].Trim() == PROCESS_ADMIN
                        || args[1].Trim() == PROCESS_MEMBER
                        || args[1].Trim() == PROCESS_GUEST
                        || args[1].Trim() == PROCESS_USER
                        )
                    {

Так что, как вы можете сказать, это своего рода беспорядок. Есть какой-то шаблон дизайна, который был бы наиболее подходящим для очистки некоторых вещей? Шаблон командования, возможно? Спасибо за совет и советы.

Ответы [ 4 ]

4 голосов
/ 17 февраля 2010

Прекратить вложение.

Вы можете переключаться, как (+1), сказал Джоэл, или вы можете просто разбить свою логику на вызовы простых методов.

if(args.Length <= 1)
{
  Console.WriteLine("Need 2 args kthx");
  return;
}
if(args.Length > 2)
{
  Console.WriteLine("More than 2 args don't know what do");
  return;
}

var arg1 = args[0].Trim();
var arg2 = args[1].Trim();

switch(arg1)
{
  case PROCESS_OPTION_ONE:
     ProcessOptionOne(arg2);
     break;
  case PROCESS_OPTION_TWO:
     ProcessOptionTwo(arg2);
     break;
  default:
     Console.WriteLine("First arg unknown I give up");
     return;
}

тогда, в ваших методах процесса ...

private static void ProcessOptionTwo(string argumentTwo)
{
  if(argumentTwo == PROCESS_CUSTOMER ||
     argumentTwo  == PROCESS_ADMIN ||
     /* etc blah blah */
}

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

3 голосов
/ 17 февраля 2010

Я неравнодушен к использованию операторов switch в массиве arguments и установке свойств в каком-либо классе конфигурации для каждого ожидаемого аргумента. Похоже, вы ожидаете очень специфически отформатированной строки аргумента, а не допускаете установки значений, вы можете попробовать:

if(args[0].Trim() == PROCESS_OPTION_ONE || args[0].Trim() == PROCESS_OPTION_TWO) 
{ 
    //Process file - Argument 2
    switch(args[1].Trim()
    {
        case PROCESS_CUSTOMER, PROCESS_ADMIN, PROCESS_MEMBER, PROCESS_GUEST, PROCESS_USER:
            // Do stuff
            break;
        default:
            // Do other stuff
            break;
    }
}

Мой предпочтительный метод будет выглядеть примерно так:

foreach(string arg in args)
{
    switch(arg)
    {
        case PROCESS_CUSTOMER:
            // Set property
            break;
        ...
        default:
            // Exception?
            break;
    }
}

ПРИМЕЧАНИЕ: args.Length == 1 быстрее, чем args.Length> 0 && args.Length <2. Это также немного более читабельно. </p>

1 голос
/ 17 февраля 2010

Я взял код из этой статьи Code Project давным-давно и создал свою собственную версию для использования в приложениях командной строки. Я внес в него свои собственные модификации, например, сделал наследование класса от Dictionary и т. Д. Но часть кода в regex очень хороша, и делает такие переключатели командной строки такими же легкими, как pie.

1 голос
/ 17 февраля 2010

Вам не нужно else, если вы уже вернулись. Это может вырезать большую часть вашего вложения. Вы также можете попробовать использовать переключатель вместо нескольких вложенных ifs.

...