Skip to content

Instantly share code, notes, and snippets.

@Y-Koji
Last active September 28, 2018 11:55
Show Gist options
  • Save Y-Koji/fadc3924b099a43e2affb13cb11320a5 to your computer and use it in GitHub Desktop.
Save Y-Koji/fadc3924b099a43e2affb13cb11320a5 to your computer and use it in GitHub Desktop.
C# 引数パーサ

C#引数パーサ

こんな感じで引数クラス作って

public class MyProgramArgument
{
    [Argument(name: "-file")]
    public string FileName { get; set; }

    [Argument(name: "-o")]
    public string OutFileName { get; set; }

    [Argument(name: "--over-write")]
    public bool IsOverWrite { get; set; }

    [Argument(name: "-process-count")]
    public int ProcessCount { get; set; }
}

こんな感じでパースする

public class Program
{
    public static void Main(string[] args)
    {
      var arg = Argument.Parse<MyProgramArgument>(args);
    }
}

適当に実行する

C:\---\Desktop> app.exe -file "C:\---\a.txt" -o "C:\---\a.out" -process-count 3 --over-write

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
public class Argument
{
public static T Parse<T>(string[] args)
{
object obj = Activator.CreateInstance<T>();
var props =
typeof(T).GetProperties()
.Where(x => null != x.GetCustomAttribute<ArgumentAttribute>())
.ToDictionary(x => x.GetCustomAttribute<ArgumentAttribute>().Name, x => x);
IList<string> unknownArgs = new List<string>();
for (int i = 0; i < args.Length; i++)
{
string arg = args[i].ToLower();
if (props.TryGetValue(arg, out PropertyInfo prop))
{
var attr = prop.GetCustomAttribute<ArgumentAttribute>();
if (attr.IsMark && prop.PropertyType == typeof(bool))
{
prop.SetValue(obj, true);
}
else
{
if (prop.PropertyType == typeof(string))
{
if (args[i + 1].StartsWith("-"))
{
throw new ArgumentException($"Not found {arg} parameter value.");
}
else
{
prop.SetValue(obj, args[i + 1]);
}
}
else if (prop.PropertyType == typeof(bool))
{
prop.SetValue(obj, true);
}
else if (null != prop.PropertyType.GetMethod("TryParse"))
{
var tryParse = prop.PropertyType.GetMethod("TryParse", BindingFlags.Static);
var parameter = new object[] { args[i + 1], null, };
if ((bool)tryParse.Invoke(null, parameter))
{
prop.SetValue(obj, parameter[1]);
}
else
{
throw new ArgumentException($"Not found {arg} parameter value.");
}
}
else
{
throw new InvalidProgramException($"{prop.PropertyType} is unknown parameter type.");
}
}
}
}
return (T)obj;
}
}
using System;
public class ArgumentAttribute : Attribute
{
public string Name { get; set; } = string.Empty;
public bool IsMark { get; set; } = false;
public ArgumentAttribute(string name = "")
{
Name = name;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment