[英]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.