Search code examples
c#linqsystem.commandline

System.CommandLine Command custom validator: how to search


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.


Solution

  • 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.";
            }
    });