我正在尝试验证命令行参数,并在出现错误时打印错误消息。
我的问题是,如果命令行参数的数量增加(目前,我只有3),那么我的代码将变成意大利面条代码。如何降低给定代码的圈复杂度?
var isCmdLineWrong = false;
var Arg1 = "Undefined";
var Arg2 = "Undefined";
var Arg3 = "Undefined";
var commandArguments = Environment.GetCommandLineArgs();
if (commandArguments.Contains("-r") && arguments[commandArguments.IndexOf("-r") + 1].StartsWith("-") == false)
Arg1 = commandArguments[commandArguments.IndexOf("-r") + 1];
else
{
isCmdLineWrong = true;
}
if (commandArguments.Contains("-n") && commandArguments[commandArguments.IndexOf("-n") + 1].StartsWith("-") == false)
Arg2 = commandArguments[commandArguments.IndexOf("-n") + 1];
else
{
isCmdLineWrong = true;
}
if (commandArguments.Contains("-p") && commandArguments[commandArguments.IndexOf("-p") + 1].StartsWith("-") == false)
Arg3 = commandArguments[commandArguments.IndexOf("-p") + 1];
else
{
isCmdLineWrong = true;
}
if (isCmdLineWrong) Console.WriteLine("Parameters structure is inconsistent");
答案 0 :(得分:4)
我建议提取 CommandLine
类:
public static class CommandLine {
private static String FindValue(string value) {
var commandArguments = Environment.GetCommandLineArgs();
int index = commandArguments.IndexOf(value);
if (index < 0)
return null;
else if (index >= commandArguments.Length - 1)
return null; // cmd like "myRoutine.exe -p"
else
return commandArguments[index + 1];
}
static CommandLine() {
Arg1 = FindValue("-r");
Arg2 = FindValue("-n");
Arg3 = FindValue("-p");
}
public static String Arg1 { get; private set; }
public static String Arg2 { get; private set; }
public static String Arg3 { get; private set; }
public static bool IsValid {
get {
return Arg1 != null && Arg2 != null && Arg3 != null;
}
}
}
写完这堂课后你可以把
if (!CommandLine.IsValid) {
Console.WriteLine("Parameters structure is inconsistent");
return;
}
if (CommandLine.Arg1 == "quit") {
...
}
答案 1 :(得分:1)
在你的代码中,最重要的一点是你做了几次完全相同的事情,尽管有不同的输入"-r"
和Arg1
,{{ 1}}和"-n"
,Arg2
和"-p"
。也就是说,您有以下代码片段出现三次(减去我的重新格式化):
Arg3
Don't Repeat Yourself (DRY) principle试图警告我们不要编写复制粘贴式重复代码,原始代码很明显违反了它。
我建议您提取公共代码并将其放在单独的方法中。例如:
if (commandArguments.Contains(…) &&
arguments[commandArguments.IndexOf(…) + 1].StartsWith("-") == false)
{
… = commandArguments[commandArguments.IndexOf(…) + 1];
}
else
{
isCmdLineWrong = true;
}
现在,您可以使用以下内容替换重复的static bool TryGetArg(string commandArguments, string name, out string value)
{
// Debug.Assert(name.StartsWith("-"));
if (commandArguments.Contains("-") &&
arguments[commandArguments.IndexOf(name) + 1].StartsWith("-") == false)
{
value = commandArguments[commandArguments.IndexOf(name) + 1];
return true;
}
else
{
value = null;
return false;
}
}
if
:
else
答案 2 :(得分:1)
这个问题是如何重用代码的简单示例。
结果是
// Returns this option's value from args, or null on error
public string OptionValue(string[] args, string option)
{
try
{
if (args.Contains(option))
{
string value = args[args.IndexOf(option) + 1]; // reuse expressions as well
if (!value.StartsWith("-"))
return value;
}
return null; // null meaning "undefined"
}
catch
{
return null;
}
}
// And now your code
string[] args = Environment.GetCommandLineArgs();
string Arg1 = OptionValue(args, "-r");
string Arg2 = OptionValue(args, "-n");
string Arg3 = OptionValue(args, "-p");
bool isCmdLineWrong = (Arg1 == null ||
Arg2 == null ||
Arg3 == null);
当然,如果您没有复制/粘贴代码,可以避免所有这些重写。