Partilhar via


Como personalizar a análise e a validação em System.CommandLine

Importante

System.CommandLine está atualmente em pré-visualização e esta documentação destina-se à versão 2.0 beta 5. Algumas informações estão relacionadas ao produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado. A Microsoft não oferece garantias, expressas ou implícitas, em relação às informações fornecidas aqui.

Por padrão, System.CommandLine fornece um conjunto de analisadores internos que podem analisar muitos tipos comuns:

  • bool
  • byte e sbyte
  • short e ushort
  • int e uint
  • long e ulong
  • float e double
  • decimal
  • DateTime e DateTimeOffset
  • DateOnlye ainda TimeOnly
  • Guid
  • FileSystemInfo, FileInfoe DirectoryInfo
  • Enums
  • matrizes e listas dos tipos listados

Outros tipos não são suportados, mas você pode criar analisadores personalizados para eles. Você também pode validar os valores analisados, o que é útil quando você deseja garantir que a entrada atenda a determinados critérios.

Validadores

Cada opção, argumento e comando pode ter um ou mais validadores. Os validadores são usados para garantir que o valor analisado atenda a determinados critérios. Por exemplo, você pode validar que um número é positivo ou que uma cadeia de caracteres não está vazia. Você também pode criar validadores complexos que verificam várias condições.

Cada tipo System.CommandLine de símbolo tem uma Validators propriedade que contém uma lista de validadores. Os validadores são executados depois que a entrada é analisada e podem relatar um erro se a validação falhar.

Para fornecer código de validação personalizado, chame System.CommandLine.Option.Validators.Add sua opção ou argumento (ou comando), conforme mostrado no exemplo a seguir:

Option<int> delayOption = new("--delay");
delayOption.Validators.Add(result =>
{
    if (result.GetValue(delayOption) < 1)
    {
        result.AddError("Must be greater than 0");
    }
});

System.CommandLine Fornece um conjunto de validadores internos que podem ser usados para validar tipos comuns:

  • AcceptExistingOnly - configura determinada opção ou argumento para aceitar apenas valores correspondentes a um arquivo ou diretório existente.
  • AcceptLegalFileNamesOnly - configura determinada opção ou argumento para aceitar apenas valores que representam nomes de arquivos legais.
  • AcceptOnlyFromAmong - configura determinada opção ou argumento para aceitar apenas valores de um conjunto especificado de valores.

Analisadores personalizados

Os analisadores personalizados são necessários para analisar tipos sem analisador padrão, como tipos complexos. Eles também podem ser usados para analisar tipos suportados de uma maneira diferente dos analisadores internos.

Suponha que você tenha um Person tipo:

public class Person
{
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
}

Você pode ler os valores e criar uma instância de Person na ação de comando.

rootCommand.SetAction(parseResult =>
{
    Person person = new()
    {
        FirstName = parseResult.GetValue(firstNameOption),
        LastName = parseResult.GetValue(lastNameOption)
    };
    DoRootCommand(parseResult.GetValue(fileOption), person);
});

Com um analisador personalizado, você pode obter um tipo personalizado da mesma forma que obtém valores primitivos:

Option<Person?> personOption = new("--person")
{
    Description = "An option whose argument is parsed as a Person",
    CustomParser = result =>
    {
        if (result.Tokens.Count != 2)
        {
            result.AddError("--person requires two arguments");
            return null;
        }
        return new Person
        {
            FirstName = result.Tokens.First().Value,
            LastName = result.Tokens.Last().Value
        };
    }
};

Se você quiser analisar e validar a entrada, use o CustomParser delegado, conforme mostrado no exemplo a seguir:

Option<int> delayOption = new("--delay")
{
    Description = "An option whose argument is parsed as an int.",
    CustomParser = result =>
    {
        if (!result.Tokens.Any())
        {
            return 42;
        }

        if (int.TryParse(result.Tokens.Single().Value, out var delay))
        {
            if (delay < 1)
            {
                result.AddError("Must be greater than 0");
            }
            return delay;
        }
        else
        {
            result.AddError("Not an int.");
            return 0; // Ignored.
        }
    }
};

Aqui estão alguns exemplos do que se pode fazer com CustomParser, mas que não se pode fazer com um validador.

  • Analise outros tipos de cadeias de caracteres de entrada (por exemplo, analise "1,2,3" em int[]).
  • Aridade dinâmica. Por exemplo, se você tiver dois argumentos definidos como matrizes de cadeia de caracteres e tiver que manipular uma sequência de cadeias de caracteres na entrada de linha de comando, o System.CommandLine.Parsing.ArgumentResult.OnlyTake método permitirá que você divida dinamicamente as cadeias de caracteres de entrada entre os argumentos.

Ver também