如何使用NDesk.Options强制执行必需的命令行选项?
我只是写了一个控制台实用程序,并决定使用NDesk.Options进行命令行解析。我的问题是,我如何执行必需的命令行选项?如何使用NDesk.Options强制执行必需的命令行选项?
我在docs看出:具有所需值
选项(附加“=”与选项名称)或可选值(追加“:”在选项名称)。
但是,当我在选项名称末尾加上=
时,行为没有区别。理想情况下,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值,因此始终为会得到以下值(除非该值已“编码”为原始选项,例如-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和private bool optionSet。
四,创建时将targetValue传递给Option。订阅PropertyChanged事件。其中,如果发件人不为空,请将“optionSet”设置为true。
将Validate()方法添加到Option类,如果targetValue不为null且optionSet为false,则会引发异常。
最后,将一个Validate()方法添加到OptionContext中,该方法将遍历所有选项并调用其各自的Validate()方法。在Parse()方法的最后调用它。
这是修改后的代码的zip:http://www.davidair.com/misc/options.zip
我有同样的问题。接缝NDesk.Options不会抛出异常。 – 2010-09-08 15:53:50