Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Value not available after Pasring #107

Closed
ericnewton76 opened this issue Nov 4, 2017 · 7 comments
Closed

Value not available after Pasring #107

ericnewton76 opened this issue Nov 4, 2017 · 7 comments

Comments

@ericnewton76
Copy link
Member

Issue by dpparekh
Wednesday Jan 18, 2017 at 20:04 GMT
Originally opened as gsscoder/commandline#405


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(args);
var x = result.Value.SomeArg
}

What am I missing?

@ericnewton76
Copy link
Member Author

Comment by nemec
Thursday Jan 19, 2017 at 06:05 GMT


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?

@ericnewton76
Copy link
Member Author

Comment by LtKlaus
Friday Mar 10, 2017 at 20:56 GMT


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
            }
        }
    }
}

@ericnewton76
Copy link
Member Author

Comment by LtKlaus
Friday Mar 10, 2017 at 23:38 GMT


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
            }

@ericnewton76
Copy link
Member Author

Comment by LtKlaus
Friday Mar 10, 2017 at 23:49 GMT


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
        }
    }

@ericnewton76
Copy link
Member Author

Comment by nemec
Saturday Mar 11, 2017 at 01:58 GMT


@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.

@ericnewton76
Copy link
Member Author

Comment by LtKlaus
Monday Mar 13, 2017 at 15:26 GMT


@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.

@moh-hassan
Copy link
Collaborator

The [Pr #634) exposes the Parsed option Value to the base class, available in develop branch and will be released in v2.9.
You can:

var result = Parser.Default.ParseArguments<Options>(args);
Options options = result.Value;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants