我只是在编写一个控制台实用程序,并决定使用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);
}
}
答案 0 :(得分:42)
问题在于文档并不像显然需要的那样清晰。 : - (
具体来说,按照:
选项规范中的=
不适用于整个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
的处理程序需要一个值,因此始终获取以下值(除非该值已“编码”到原始选项中,例如{{1 }})。
第二个重要的地方是,当需要值的选项是最后一个选项时,并且没有值存在的值:
-a=value
这将抛出一个OptionException,因为options.Parse(new[]{"-a"});
的处理程序需要一个值,并且不存在任何值。
因此,如果您有一个自己需要的选项(而不是需要值的选项),您需要手动检查:
-a
答案 1 :(得分:2)
可以稍微扩展NDesk.Options以添加此功能。
首先,创建一个实现INotifyPropertyChanged的SetupOption类:
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。
向Option类添加一个Validate()方法,如果targetValue不为null且optionSet为false,则抛出异常。
最后,向OptionContext添加一个Validate()方法,该方法将遍历所有选项并调用它们各自的Validate()方法。在Parse()方法的最后调用它。
以下是修改后代码的zip:http://www.davidair.com/misc/options.zip