Очистка потока управления при работе с аргументами командной строки [C#]
-
21-09-2019 - |
Вопрос
Я имею дело с программой, которая выполняет множество ветвлений 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
)
{
Так что, как вы можете сказать, это своего рода беспорядок.Есть ли один или два шаблона проектирования, которые были бы наиболее применимы для некоторой очистки?Возможно, командный шаблон?Спасибо за советы.
Решение
Я неравнодушен к использованию операторов 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;
}
}
ПРИМЕЧАНИЕ:аргументы.Длина == 1 быстрее, чем аргументы.Длина > 0 && аргументы.Длина < 2.Это также немного более читабельно.
Другие советы
Прекратите гнездиться.
Вы можете переключиться, как сказал (+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 */
}
Делайте свои методы как можно более простыми и разбивайте более длинные, сбивающие с толку алгоритмы на отдельные вызовы методов, которые по своему названию дают четкое представление о том, что они делают.
Вам не нужно else
если вы уже вернулись.Это может сократить большую часть вашей вложенности.Вы также могли бы попробовать использовать switch вместо кучи вложенных ifs.
Я взял код из этой статьи Code Project давным-давно и создал свою собственную версию для использования в приложениях командной строки.Я внес в него свои собственные изменения, например, сделал класс наследуемым от Dictionary и т.д.Но часть кода с регулярными выражениями очень хороша и упрощает такого рода переключение командной строки.