Home > Net >  System.CommandLine Command custom validator: how to search
System.CommandLine Command custom validator: how to search

Time:12-28

I am writing a C# console application project (.NET 7.0) using Visual Studio for macOS 2022 v17.4 and System.CommandLine (2.0.0-beta4.22272.1).

I am trying to add a custom validator to one of my Commands, and found the following code snippet on the project's GitHub site:

        this.AddValidator(commandResult =>
        {
            if (commandResult.Children.Contains("one") &&
                commandResult.Children.Contains("two"))
            {
               commandResult.ErrorMessage = "Options '--one' and '--two' cannot be used together.";
            }
        });

However, it will not compile in my command, due to Error CS1929: 'IReadOnlyList' does not contain a definition for 'Contains' and the best extension method overload 'MemoryExtensions.Contains(ReadOnlySpan, string)' requires a receiver of type 'ReadOnlySpan' (CS1929).

I have looked for the appropriate extension method in the various System.CommandLine namespaces, but I don't see anything. (Yes, I included the System.Linq namespace.)

Can anyone suggest what is amiss?

Edit: The original code which I "borrowed" is this:

        command.AddValidator(commandResult =>
        {
            if (commandResult.Children.Contains("one") &&
                commandResult.Children.Contains("two"))
            {
                return "Options '--one' and '--two' cannot be used together.";
            }

            return null;
        });

Note that this delegate returns a value, while the updated one does not, but instead sets ErrorMessage. That's one breaking change in System.CommandLine, and it's plausible that the issue here is due to another breaking change. The System.CommandLine project does note that the project is in a state of flux and subject to changes.

CodePudding user response:

I have no experience with this specific library, but peeking its source hints that the collection you are calling .Contains() on doesn't contain Strings, but rather instances of SymbolResult, hence it cannot find suitable overload for the method you are trying to call.

I couldn't find the code you provided anywhere from mentioned GitHub repo, but instead found this piece of code from this test file of library:

command.Validators.Add(commandResult =>
{
    if (commandResult.Children.Any(sr => sr.Symbol is IdentifierSymbol id && id.HasAlias("--one")) &&
        commandResult.Children.Any(sr => sr.Symbol is IdentifierSymbol id && id.HasAlias("--two")))
        {
            commandResult.ErrorMessage = "Options '--one' and '--two' cannot be used together.";
        }
});

CodePudding user response:

The extension method you need is defined as part of the class System.Linq.Enumerable. So you need using System.Linq; at the top of your class file.

But that won't help if your project doesn't reference the assembly System.Linq.dll. (I don't know why it wouldn't, just out of the box, but perhaps it doesn't.) So you may need to add a reference for that.

  • Related