我正在尝试以下列方式使用 OptionSet
类:
string resultsFileName = null;
bool isHelp = false;
var p = new OptionSet() {
{ "r=|resultsFile=", "The file with the results", v => { resultsFileName = v; } }
{ "h|help", "Show this help", v => { isHelp = (v != null); } },
};
try
{
p.Parse(args);
}
catch (OptionException e)
{
Console.WriteLine("Invalid arguments: " + e.Message);
ShowHelp(p);
return;
}
因此,resultsFile
选项预计是必需的(根据文档:http://www.ndesk.org/doc/ndesk-options/NDesk.Options/OptionValueType.html)。但是,当我按原样运行程序(即没有命令行参数)时,不会抛出异常。请协助。
更新:在调试器中,当没有提供命令行选项时,private void AssertValid (int index)
方法将永远不会到达throw新的 OptionException
。
这是 How to enforce required command-line options with NDesk.Options? 的副本, 和 answer is the same : NDesk.Options 不支持。
引用我自己的话:
根据 OptionValueType.Required docs,选项规范中的 =
不适用于整个 OptionSet,而仅适用于该特定选项的值。
这个的重要性实际上只在两种情况下相关,所以首先让我们考虑 OptionSet 解析器:
string a = null;
string b = null;
var options = new OptionSet {
{ "a=", v => a = v },
{ "b=", v => b = v },
};
场景 1 重要的是 OptionSet.Parse() 以单次传递、仅向前的方式工作,并且不查看选项值以确定它们是否“应该”值.因此,考虑:
options.Parse(new[]{"-a", "-b"});
这将是 a
的值为 "-b"
,而 b
为 null
。由于 -a
的处理程序需要一个值,它总是得到以下值(除非该值被“编码”到原始选项中,例如 -a=value
)。
第二个重要的地方是当一个需要值的选项是最后一个选项,并且没有它的值时:
options.Parse(new[]{"-a"});
这将抛出 OptionException,因为 -a
的处理程序 需要 一个值,但没有值存在。
因此,如果您有一个选项本身是必需的(而不是一个需要值的选项),您需要手动检查:
string dir = null;
new OptionSet {
{ "o=", v => dir = v },
}.Parse (args);
if (dir == null)
throw new InvalidOperationException ("Missing required option -o=DIR");