commandline
commandline copied to clipboard
Value not available after Pasring
I am doing the following thing in my code but there is a compile time error that Value isn't part of result.
static void Main(string[] args) { var result = Parser.Default.ParseArguments<Options>(args); var x = result.Value.SomeArg }
What am I missing?
You need to use the generic version of the ParseArguments
method, otherwise the parser doesn't know what kind of arguments are available to parse.
If that doesn't solve the problem, can you post your options class as well?
I'm trying to figure out the same thing. I'm using v2.1.1-beta. I'm trying to create a program that will support different commands. I'm using ParseArguments and passing in the possible types using the options classes I created.
A simple example is below. When I run this in the debugger I can see that parserResults has a property called Value and it's of type SecondCommandOptions. When typing out the code, there's no Value property on the parserResults object.
How can I get the Value from parserResults so I can get it's type and cast it to the appropriate options class?
using CommandLine;
namespace TestCommandLineArguments
{
[Verb("firstcommand")]
internal class FirstCommandOptions
{
[Option("setting")]
public string Setting { get; set; }
}
[Verb("secondcommand")]
internal class SecondCommandOptions
{
[Option("setting")]
public string Setting { get; set; }
}
internal class Program
{
private static void Main(string[] args)
{
args = new[] {"secondcommand", "--setting", "value"};
var parserResults = Parser.Default.ParseArguments(args, typeof(FirstCommandOptions), typeof(SecondCommandOptions));
if (parserResults.Tag == ParserResultType.Parsed)
{
//If I uncomment the following line I get : Cannot resolve symbol 'Value'
//var value = parserResults.Value;
//Do something based on what options class was created
}
}
}
}
I was able to get Value using Reflection and was able to cast it to my options classes. I'm not sure why the Value property isn't accessible without using Reflection.
var type = parserResults.GetType();
var prop = type.GetProperty("Value");
var value = prop.GetValue(parserResults);
if (value is FirstCommandOptions)
{
var commandOptions = value as FirstCommandOptions;
//Run my first command
}
if (value is SecondCommandOptions)
{
var commandOptions = value as SecondCommandOptions;
//Run my second command
}
Actually Reflection isn't needed and I realized why. I wasn't paying attention to the return value from ParseArguments which is ParserResult< object > and that can cast to Parsed< object > or NotParsed< object >. I just needed to parse it to Parsed< object > then I could access Value and could then check the type of Value and cast it to the appropriate options class.
Hope this will help someone else figure this out quicker than I did. Spent more time scratching my head than I would like to admit.
```
private static void Main(string[] args)
{
args = new[] {"secondcommand", "--setting", "value"};
var parserResults = Parser.Default.ParseArguments(args, typeof(FirstCommandOptions), typeof(SecondCommandOptions));
if (parserResults.Tag == ParserResultType.Parsed)
{
var parsed = parserResults as Parsed<object>;
var value = parsed.Value;
//Then figure out the type of "value" and continue on
}
}
@LtKlaus there are two methods on ParserResult: WithParsed
and WithNotParsed
. Those do the appropriate conversion for you. It's a bit of a 'functional' way of doing things.
@nemec Thanks. I just had a look at those methods and gave them a quick test. They do the conversion for me but with the drawback of not being able to return a value. My current method that processes the Value will return the command that's associated with the options class that was created. I'd have to make a few changes in my code to handle the commands differently but it's do able and worth a look.
This new version of the parser is a setback implementing the WithParsedResult And WithNotParsed...
I am rolling back to version 1.9.71.2 stable, where the options class get initialized with the values - easy peasy.
I scratched my head for about 20 minutes on this wondering why it was so difficult to use.
Ended up using this solution, but it is very strange to have to declare a lambda with an external reference just to pass back out. The rest of my app isn't setup to use the functional style
Options options;
Parser.Default.ParseArguments<Options>(args).WithParsed(opts => { options = opts; });
Ideally I'd just like to be able to do something this simple:
var options = Parser.Default.ParseArguments<Options>(args);