C# 如何使用NDesk.options强制执行所需的命令行选项?

C# 如何使用NDesk.options强制执行所需的命令行选项?,c#,console-application,command-line-arguments,ndesk.options,C#,Console Application,Command Line Arguments,Ndesk.options,我刚刚编写了一个控制台实用程序,并决定使用NDesk.Options进行命令行解析。我的问题是,如何强制执行所需的命令行选项 我在报告中看到: 具有必需值(将“=”附加到选项名称)或可选值(将“:”附加到选项名称)的选项 但是,当我在选项名称的末尾添加一个=时,行为没有区别。理想情况下,解析方法会引发异常 我还有别的事要做吗 以下是我的测试代码: class Program { static void Main(string[] args) { bool show

我刚刚编写了一个控制台实用程序,并决定使用NDesk.Options进行命令行解析。我的问题是,如何强制执行所需的命令行选项

我在报告中看到:

具有必需值(将“=”附加到选项名称)或可选值(将“:”附加到选项名称)的选项

但是,当我在选项名称的末尾添加一个
=
时,行为没有区别。理想情况下,解析方法会引发异常

我还有别的事要做吗

以下是我的测试代码:

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);
    }
}
类程序
{
静态void Main(字符串[]参数)
{
bool show_help=false;
字符串someoption=null;
var p=新OptionSet(){
{“someoption=”,“somestringoption”,v=>someoption=v},
{“h|help”,“显示此消息并退出”,v=>show|help=v!=null}
};
额外列出;
尝试
{
额外=p.Parse(args);
}
捕获(OptionException e)
{
System.Console.Write(“myconsole:”);
系统控制台写入线(e.Message);
System.Console.WriteLine(“有关更多信息,请尝试使用'myconsole--help'”);
返回;
}
如果(显示帮助)
{
ShowHelp(p);
返回;
}
System.Console.WriteLine(“============================”);
System.Console.WriteLine(someoption);
}
静态无效显示帮助(Optip)
{
System.Console.WriteLine(“用法:myconsole[OPTIONS]”);
System.Console.WriteLine();
System.Console.WriteLine(“选项:”);
p、 WriteOptions描述(System.Console.Out);
}
}

问题在于文档并不像表面上需要的那样清晰:-(

具体而言,根据:

选项规范中的
=
不适用于OptionSet作为一个整体,而仅适用于该特定选项的值

<>这很重要,它只在两个场景中相关,所以首先让我们考虑OpTySSET解析器:

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来添加此功能

首先,创建将实现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"));
            }
        }
    }
}
类设置选项:INotifyPropertyChanged
{
#区域INotifyProperty更改成员
公共事件属性更改事件处理程序属性更改;
#端区
私人T_值;
公共价值
{
得到
{
返回_值;
}
设置
{
_价值=价值;
if(PropertyChanged!=null)
{
PropertyChanged(_值,新PropertyChangedEventArgs(“值”));
}
}
}
}
其次,将重载添加到ActionOption,该选项将INotifyPropertyChanged的实例作为参数(称为targetValue)

第三,修改选项类以添加私有INotifyPropertyChanged targetValue和私有bool optionSet

第四,在创建选项时将targetValue传递给该选项。订阅PropertyChanged事件。在该事件中,如果发送方不为null,则将“optionSet”设置为true

向选项类添加Validate()方法,如果targetValue不为null且optionSet为false,该方法将引发异常

最后,向OptionContext添加一个Validate()方法,该方法将循环所有选项并调用它们各自的Validate()方法


下面是修改代码的邮政编码:

我也有同样的问题。Seams NDesk.Options不会引发异常。