我有一个(希望)简单的C#问题。
我在程序中解析参数,从命令行读取文件,我允许短参数和长参数作为输入(因此我的scenario / f和文件都是有效)
上述任一参数之后的值应该是要读取的文件名。
我想要做的是根据所选择的参数在数组中找到此文件名,并将其复制到字符串中,同时不留任何漏洞。
我有正常运行的代码,但我不确定它是“高效”(并且是安全的)。
代码(删除了注释和写入):
if ( args.Contains("/f") || args.Contains("file"))
{
int pos = Array.IndexOf(args, "/f");
if (pos == -1)
pos = Array.IndexOf(args, "file");
if (pos > -1)
pos++;
inputFile = (args[pos]);
if (File.Exists(inputFile) == false)
{
Environment.Exit(0);
}
}
是否有更有效的方法来执行此操作,可能在初始if语句中使用一些漂亮的逻辑来检查哪个参数有效,然后对该参数进行单一检查? 使用4 ifs和2 Array.IndexOf似乎很糟糕,只是为了支持2种不同的方式来允许有人说他们想要输入文件......
谢谢!如果这看起来微不足道或者不是SO的意思,我很抱歉。不幸的是,我没有任何真正的方法来获得有关我的编码实践的反馈。
答案 0 :(得分:3)
您的解决方案不会很好地扩展。想象一下,你有两个不同的参数,包括短形式和长形式。这将是多少条件和索引检查?
最好使用现有工具(例如Command Line Parser Library)进行参数解析。
答案 1 :(得分:0)
您可以根据自己的特定需求编写一个简单的参数解析器,并且仍然支持" new"场景。例如,在您的输入法中有
// The main entry point for the application.
[STAThread]
static void Main(string[] args)
{
// Parse input args
var parser = new InputArgumentsParser();
parser.Parse(args);
....
}
您的InputArgumentsParser
可能类似于
public class InputArgumentsParser
{
private const char ArgSeparator = ':';
private Dictionary<string[],Action<string>> ArgAction =
new Dictionary<string[],Action<string>>();
public InputArgumentsParser()
{
// Supported actions to take, based on args
ArgAction.Add(new[] { "/f", "/file" }, (param) =>
Console.WriteLine(@"Received file argument '{0}'", param));
}
/// Parse collection, expected format is "<key>:<value>"
public void Parse(ICollection<string> args)
{
if (args == null || !args.Any())
return;
// Iterate over arguments, extract key/value pairs
foreach (string arg in args)
{
string[] parts = arg.Split(ArgSeparator);
if (parts.Length != 2)
continue;
// Find related action and execute if found
var action = ArgAction.Keys.Where(key =>
key.Contains(parts[0].ToLowerInvariant()))
.Select(key => ArgAction[key]).SingleOrDefault();
if (action != null)
action.Invoke(parts[1]);
else
Console.WriteLine(@"No action for argument '{0}'", arg);
}
}
}
在这种情况下,/f:myfile.txt
或/file:myfile.txt
会向控制台吐出
收到文件参数&#39; myfile.txt&#39;
答案 2 :(得分:0)
我在您提供的代码中看到的一个问题是,如果/f
或file
是最后一个参数,它将会失败。
如果您不想编写或使用完整的参数解析代码,则以下代码的效果会稍好一些。
var fileArguments = new string[] { "/f", "file" };
int fileArgIndex = Array.FindIndex(args,
arg => fileArguments.Contains(arg.ToLowerInvariant()));
if (fileArgIndex != -1 && fileArgIndex < args.Length - 1)
{
inputFile = args[fileArgIndex + 1];
if (!File.Exists(inputFile))
{
Environment.Exit(0);
}
}