[英]How to enforce required command-line options with NDesk.Options?
我只是在编写一个控制台实用程序,并决定使用NDesk.Options进行命令行解析。 我的问题是,如何执行必需的命令行选项?
我在文档中看到:
具有必需值(在选项名称后附加'=')或可选值(在选项名称后附加':')的选项。
但是,当我在选项名称的末尾添加=
时,行为没有区别。 理想情况下,Parse方法将引发异常。
还有什么我需要做的吗?
这是我的测试代码:
class Program
{
static void Main(string[] args)
{
bool show_help = false;
string someoption = null;
var p = new OptionSet() {
{ "someoption=", "Some String Option", v => someoption = v},
{ "h|help", "show this message and exit", v => show_help = v != null }
};
List<string> extra;
try
{
extra = p.Parse(args);
}
catch (OptionException e)
{
System.Console.Write("myconsole: ");
System.Console.WriteLine(e.Message);
System.Console.WriteLine("Try `myconsole --help' for more information.");
return;
}
if (show_help)
{
ShowHelp(p);
return;
}
System.Console.WriteLine("==================");
System.Console.WriteLine(someoption);
}
static void ShowHelp(OptionSet p)
{
System.Console.WriteLine("Usage: myconsole [OPTIONS]");
System.Console.WriteLine();
System.Console.WriteLine("Options:");
p.WriteOptionDescriptions(System.Console.Out);
}
}
问题在于文档不像显然需要的那样清晰。 :-(
具体来说,按照:
选项规范中的=
不适用于整个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");
可以稍微扩展NDesk.Options以添加此功能。
首先,创建一个SetupOption类,该类将实现INotifyPropertyChanged:
class SetupOption<T> : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
private T _value;
public T Value
{
get
{
return _value;
}
set
{
_value = value;
if (PropertyChanged != null)
{
PropertyChanged(_value, new PropertyChangedEventArgs("Value"));
}
}
}
}
其次,向ActionOption添加重载,该重载将INotifyPropertyChanged的实例作为参数(称为targetValue)。
第三,修改Option类以添加私有INotifyPropertyChanged targetValue和私有bool optionSet。
第四,在创建目标值时将其传递给Option。 订阅PropertyChanged事件。 如果发件人不为null,则在其中将“ optionSet”设置为true。
如果目标值不为null且optionSet为false,则将Validate()方法添加到Option类,该方法将引发异常。
最后,向OptionContext添加Validate()方法,该方法将遍历所有选项并调用它们各自的Validate()方法。 在Parse()方法的最后调用它。
这是修改后的代码的zip: http : //www.davidair.com/misc/options.zip
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.