C#检查数组的值,转到现有值的位置

时间:2015-02-05 11:26:55

标签: c# arrays string performance

我有一个(希望)简单的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的意思,我很抱歉。不幸的是,我没有任何真正的方法来获得有关我的编码实践的反馈。

3 个答案:

答案 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)

我在您提供的代码中看到的一个问题是,如果/ffile是最后一个参数,它将会失败。

如果您不想编写或使用完整的参数解析代码,则以下代码的效果会稍好一些。

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);
    }
}