NDesk.Options使用详解(Mono.Options)
参考自http://www.ndesk.org/doc/ndesk-options/NDesk.Options/index.html写在前面国内貌似还没有关于NDesk.Options的中文介绍,因此在官方教程基础上,对NDesk.Options进行简单总结介绍。个人水平有限,不能很好的表达原作者意图,请各位见谅!总体介绍NDesk.Options是用于C#命令行参数解析的开源...
参考自http://www.ndesk.org/doc/ndesk-options/NDesk.Options/index.html
写在前面
国内貌似还没有关于NDesk.Options的中文介绍,因此在官方教程基础上,对NDesk.Options进行简单总结介绍。
个人水平有限,不能很好的表达原作者意图,请各位见谅!
总体介绍
NDesk.Options是用于C#命令行参数解析的开源库,又名Mono.Options。支持解析布尔参数(Boolean Options)、值参数(Value Options)、捆绑参数(Bundled parameters)。在进行参数解析的时候,允许自定义回调函数。
官方网页地址为http://www.ndesk.org/Options
Github上地址为https://github.com/mono/mono/tree/master/mcs/class/Mono.Options/
代码示例
准备通过官方例子,讲解NDesk.Options的用法。如果有时间和精力再继续完善补充更多例子。
全篇文章将根据该示例进行讲解,请先大体了解下代码结构,后面会对NDesk.Options用法进行介绍。
using NDesk.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NDeskOptionDemo
{
class Program
{
static int verbosity;
public static void Main(string[] args)
{
bool show_help = false;
List<string> names = new List<string>();
int repeat = 1;
// 第一阶段:初始化
var p = new OptionSet() {
// 注册 解析必填参数(required)、参数描述、解析回调函数
{ "n|name=", "the {NAME} of someone to greet.",
v => names.Add (v) },
// 注册解析必填参数(required)、参数描述、解析回调函数
{ "r|repeat=",
"the number of {TIMES} to repeat the greeting.\n" +
"this must be an integer.",
(int v) => repeat = v },
// 注册解析布尔参数(boolean)、参数描述、解析回调函数
{ "v", "increase debug message verbosity",
v => { if (v != null) ++verbosity; } },
// 注册解析布尔参数(boolean)、参数描述、解析回调函数
{ "h|help", "show this message and exit",
v => show_help = v != null },
};
List<string> extra;
try
{
// 第二阶段:解析,未解析的参数将放置到变量extra中
extra = p.Parse(args);
}
catch (OptionException e)
{
Console.Write("greet: ");
Console.WriteLine(e.Message);
Console.WriteLine("Try `greet --help' for more information.");
return;
}
if (show_help)
{
ShowHelp(p);
return;
}
string message;
if (extra.Count > 0)
{
message = string.Join(" ", extra.ToArray());
Debug("Using new message: {0}", message);
}
else
{
message = "Hello {0}!";
Debug("Using default message: {0}", message);
}
foreach (string name in names)
{
for (int i = 0; i < repeat; ++i)
{
//Console.WriteLine("-------------in loop--------------");
//Console.WriteLine("message = {0}", message);
//Console.WriteLine("name[{0}] = {1}", i, name);
Console.WriteLine(message, name);
}
}
Console.ReadKey();
}
static void ShowHelp(OptionSet p)
{
Console.WriteLine("Usage: greet [OPTIONS]+ message");
Console.WriteLine("Greet a list of individuals with an optional message.");
Console.WriteLine("If no message is specified, a generic greeting is used.");
Console.WriteLine();
Console.WriteLine("Options:");
p.WriteOptionDescriptions(Console.Out);
}
static void Debug(string format, params object[] args)
{
if (verbosity > 0)
{
Console.Write("# ");
Console.WriteLine(format, args);
}
}
}
}
使用介绍
参数解析分为两个阶段:初始化和解析。分别对应上面代码var p = new OptionSet() {...} 和p.Parse(args);
NDesk.Options会把“-”、“--”、“/”认为是参数名(OptionName)进行解析并赋予参数值(OptionValue),举例说明
a.exe -n 10 --name=9 /opt:true ?123
经解析后,参数名n的参数值为10,name的值为9,opt的值为true。而?123是未被处理的多余字符串。在未定义默认解析函数情况下,经解析后多余字符串会通过parse()函数返回,例如下面的extra就存放了多余字符串:
public static void Main(string[] args)
{
...
List<string> extra = p.Parse(args);
...
}
关于默认解析函数请参考下一节内容
初始化
初始化的目的对于使用者来说就是注册要解析的参数名、参数名的描述以及匹配到参数名后的回调函数。例如
var p = new OptionSet() {{ "n|name=", "the {NAME} of someone to greet.", v => names.Add (v) }}
- "n|name=" 表示参数名原型(Prototype),此处表示该参数名可以缩写为-n或者全称-name(注意先要声明参数名缩写,再声明参数名全称)
- "the {NAME} of someone to greet."作用时在调用p.WriteOptionDescriptions(Console.Out)后,将打印出该参数名的描述
- v => names.Add (v)表示在解析到参数名n时将参数值添加到names中(lamda表达式)
如果想为这些未匹配的参数名提供默认解析函数,可以这样注册,注意“<>”这个参数名即为默认解析函数
var p = new OptionSet() {
{ "n|name=", "the {NAME} of someone to greet.", v => names.Add (v) },
{ "<>", v => Console.WriteLine ("default handler: {0}", v)}
}
参数名有三种类型:布尔型(Boolean)、必输型(Required)、选输型(Optional),用无符号、等号、冒号来区别
var p = new OptionSet() {
//布尔,例如采用-opt+、--opt-、/opt均可以为赋值
{ "o|opt", "the {opt} of someone to greet.", v => flag = (v == null) },
//必输
{ "n2|name2=", "the {NAME2} of someone to greet.", v => names.Add (v) },
//选输
{ "n3|name3", "the {NAME3} of someone to greet.", v => names.Add (v) },
}
解析
通例子来说明参数解析,以加深对NDesk.Options的理解。仍然考虑代码示例章节的代码
##show_help为真,执行ShowHelp(p);打印参数名描述
greet.exe --help
Usage: greet [OPTIONS]+ message
Greet a list of individuals with an optional message.
If no message is specified, a generic greeting is used.
Options:
-n, --name=NAME the NAME of someone to greet.
-r, --repeat=TIMES the number of TIMES to repeat the greeting.
this must be an integer.
-v increase debug message verbosity
-h, --help show this message and exit
##v为false,不打印调试信息
##names包含A、B、C、D、E参数值
##extra为空,表示无未处理的字符串,则按照hello XXX!进行打印
##repeat未解析到,采用默认值1,即重复打印1次
greet.exe -v- -n A -name=B --name=C /name D -nE
Hello A!
Hello B!
Hello C!
Hello D!
Hello E!
##v为true,打印调试信息
##names包含E参数值
##extra为 custom greeting for: {0},则按照custom greeting for: XXX进行打印
greet.exe -v -n E custom greeting for: {0}
# Using new message: custom greeting for: {0}
custom greeting for: E
##names包含A参数值
##extra为空,表示无未处理的字符串,则按照hello XXX!进行打印
##repeat为3,重复打印3次
greet.exe -r 3 -n A
Hello A!
Hello A!
Hello A!
##repeat只能接受int类型,不能将not-an-int转换成int,抛出异常
##源代码中关于reapeat类型检查,代码为(int v) => repeat = v
greet.exe -r not-an-int
greet: Could not convert string `not-an-int' to type Int32 for option `-r'.
Try `greet --help' for more information.
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)