Compartilhar via


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

Importante

System.CommandLine está atualmente em VERSÃO PRÉVIA e essa documentação é para a versão 2.0 beta 5. Algumas informações referem-se 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 TimeOnly
  • Guid
  • FileSystemInfo, FileInfo, e DirectoryInfo
  • enumerações
  • matrizes e listas dos tipos listados

Não há suporte para outros tipos, 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 podem 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 de System.CommandLine 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 arquivo legais.
  • AcceptOnlyFromAmong – configura determinada opção ou argumento para aceitar apenas valores de um conjunto de valores especificado.

Analisadores personalizados

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 com suporte 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 da ação de Person 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 maneira 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 você pode fazer com CustomParser que você não pode fazer com um validador:

  • Analisar outros tipos de cadeias de caracteres de entrada (por exemplo, analisar "1,2,3" em int[]).
  • Aridade dinâmica. Por exemplo, se você tiver dois argumentos definidos como matrizes de cadeia de caracteres e precisar lidar com uma sequência de cadeias de caracteres na entrada da 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.

Consulte também