CommandLineParser のすすめ


コンソールアプリでオプションを指定させたい

.NET Frameworkを使って開発していたら、当然オプション指定はかかせないですよね。
でもコマンドライン引数から「-X」みたいなのを判断して処理するのがめんどくさい!
という人に最適なライブラリがあります。

CommandLineParser
Nugetはこちら → https://www.nuget.org/packages/CommandLineParser/2.4.3

です。

CommandLineParserとは

自分で作ったオプションクラスに属性を指定するだけで、プロパティやフィールドに指定オプションの値を入れてくれる優れものです。

サンプルコード

まずはオプションクラス

Option.cs
enum HogeInfo
{
    Hoge, Fuga, Piyo
}

class Options
{
    // -a と -aaa の二つ指定可能
    [Option('a', "aaa", Required = false, HelpText = "Aの説明です。")]
    public string A { get; set; }
    // string 以外でも受け取れる(この場合はオプションがあるかどうか)
    [Option('b', "bbb", Required = false, HelpText = "Bの説明です。")]
    public bool B { get; set; }
    // Sepalatorで指定下文字を区切り文字として、複数の値を渡せる
    [Option('c', "ccc", Separator = ',', HelpText = "Cの説明です。")]
    public IEnumerable<string> C { get; set; }
    // enumもいける(Hoge, Fuga などと指定する)
    [Option('d', "ddd", HelpText = "Cの説明です。")]
    public HogeInfo D { get; set; }
    // 上記指定以外のオプションや文字列が入る
    [Value(1, MetaName = "Others")]
    public IEnumerable<string> Others { get; set; }
}

コンソールアプリ本体

Program.cs
class Program
{
    static void Main(string[] args)
    {
        // ジェネリクスでオプションクラスを指定し、パースする
        var parseResult = Parser.Default.ParseArguments<Options>(args);
        Options opt = null;

        // 結果はTagに入っている
        switch(parseResult.Tag)
        {
            // パース成功
            case ParserResultType.Parsed:
                // パースの成否でパース結果のオブジェクトの方が変わる
                var parsed = parseResult as Parsed<Options>;

                // 成功時はキャストしたオブジェクトからパース結果が取得可能
                opt = parsed.Value;

                // 表示用に整形
                string strC = string.Concat("{ ", string.Join(", ", opt.C.Select(e => $"\"{e}\"")), " }");
                string strOthers = string.Concat("{ ", string.Join(", ", opt.Others.Select(e => $"\"{e}\"")), " }");

                Console.WriteLine($"opt.A = {opt.A}");
                Console.WriteLine($"opt.B = {opt.B}");
                Console.WriteLine($"opt.C = {strC}");
                Console.WriteLine($"opt.D = {opt.D}");
                Console.WriteLine($"opt.Others = {strOthers}");

                break;
            // パース失敗
            case ParserResultType.NotParsed:
                // パースの成否でパース結果のオブジェクトの方が変わる
                var notParsed = parseResult as NotParsed<Options>;

                break;
        }
    }
}

結果がTagに入っていて、Parseした結果のオブジェクトをキャストする形になるのがちょっと独特だったかな?

Help機能についてはわかってないので割愛。

結果

コマンドラインに以下を入力

> CommandLineParserTest.exe -a aaaaa --bbb -c 1,2,a,b -d Fuga foo bar foobar

※上記のサンプルコードのコンソールアプリ名が「CommandLineParserTest.exe」です。

結果は以下

opt.A = aaaaa
opt.B = True
opt.C = { "1", "2", "a", "b" }
opt.D = Fuga
opt.Others = { "foo", "bar", "foobar" }

おー、Parseするだけで全部入ってるし、これならどのコマンドライン引数がどのプロパティ(フィールド)に対応してるか一目瞭然ですね。

参考(むしろこの記事より見るべき)

こちらの記事を参考にしました。
サンプルコードなんかは体裁が一緒だと思います。
https://qiita.com/skitoy4321/items/742d143b069569014769

注意点

CommandLineParser は2019年02月現在、ver 2.4.3 ですが、こちらは .NET Standard 2.0 が対象です。
.NET Framework 4.0 などで使用したい場合は ver 2.3.0 を使いましょう。
(それ以前の .NET Framework 3.5 以前については試してないが、バージョンを下げればいけるのではないか)

ライセンスはMITライセンスなので、公開する場合はちゃんとコピーライトを書きましょう。