很多不同类的命令行参数

nic*_*ick 2 c# command-line parsing design-patterns

我们使用特定的软件来执行我的控制台应用程序有很多参数(现在它是25(!),可能会越来越多).当然,不同的类需要不同的论点.我用NDesk.Options解析它.但是,我一次又一次地为所有班级做过.

class A {
    A (IEnumerable<String> args){
        new OptionSet {
            { "arg1=", value => foo1 = value },
                { "arg2=", value => foo2 = value },
            ...
        }.Parse(args);
    }
}
class B {
    B (IEnumerable<String> args){
        new OptionSet {
            { "arg10=", value => foo10 = value },
                { "arg11=", value => foo11 = value },
            ...
        }.Parse(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

如何做好设计呢?解析静态类中的所有参数并使用它或其他东西?

Mar*_*ann 6

由于您要求设计模式,这听起来像是Interpreter模式的工作.

否则,根据我的经验,命令行参数'解析'是模式匹配的一个很好的例子,不幸的是,C#没有,但F#没有.在ZeroToNine中,参数匹配当前如下所示:

let Parse argv =
    match argv |> Seq.toList with
    | ["-l"] -> ListVersions
    | ["-a"; IsProperVersionString version] -> Assign version
    | ["-i"; "major"] -> Increment Rank.Major
    | ["-i"; "minor"] -> Increment Rank.Minor
    | ["-i"; "build"] -> Increment Rank.Build
    | ["-i"; "patch"] -> Increment Rank.Build
    | ["-i"; "revision"] -> Increment Rank.Revision
    | ["-a"; "major"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Major, rankValue)
    | ["-a"; "minor"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Minor, rankValue)
    | ["-a"; "build"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Build, rankValue)
    | ["-a"; "patch"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Build, rankValue)
    | ["-a"; "revision"; IntegerGreaterThanOrEqualToZero rankValue] -> AssignRank(Rank.Revision, rankValue)
    | ["-?"] -> ShowHelp
    | ["-h"] -> ShowHelp
    | [] -> ShowHelp
    | x -> Unknown(x)
    |> Seq.singleton
Run Code Online (Sandbox Code Playgroud)

当然,我们没有25个不同的参数,但上面的例子仍然可以让你很好地理解处理各种情况是多么容易.

即使你有一个C#代码库,你也可以在F#中编写一个解析器库.

稍微不同的说明:如果您的控制台应用程序需要25个不同的参数,将它分成几个较小的控制台应用程序是否有意义?听起来它做得很多.