Especificar argumentos de método nomeados e opcionais

Concluído

Os argumentos nomeados permitem que você especifique um argumento para um parâmetro combinando o argumento com seu nome, em vez de com sua posição na lista de parâmetros. Argumentos opcionais permitem omitir argumentos para alguns parâmetros. Ambas as técnicas podem ser usadas com métodos, indexadores, construtores e delegados.

Quando você usa argumentos nomeados e opcionais, os argumentos são avaliados na ordem em que aparecem na lista de argumentos, não na lista de parâmetros.

Parâmetros nomeados e opcionais permitem fornecer argumentos para parâmetros selecionados. Essa funcionalidade facilita muito as chamadas para interfaces COM, como as APIs de Automação do Microsoft Office.

Argumentos nomeados

Argumentos nomeados liberam você de corresponder a ordem dos argumentos à ordem dos parâmetros nas listas de parâmetros dos métodos chamados. O argumento para cada parâmetro pode ser especificado pelo nome do parâmetro.

Nota

Os argumentos nomeados melhoram a legibilidade do código identificando o que cada argumento representa.

Considere um método que usa a seguinte assinatura de método:


static void PrintOrderDetails(string sellerName, int orderNum, string productName)
{
    // Code to print the order details
}

Esse método pode ser chamado com êxito sem usar argumentos nomeados, desde que os argumentos estejam na ordem correta (definida pela assinatura do método):


PrintOrderDetails("Gift Shop", 31, "Red Mug");

Se você não se lembrar da ordem dos parâmetros, mas souber seus nomes, poderá enviar os argumentos em qualquer ordem.


PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);

Quando usados com argumentos posicionais, os argumentos nomeados são válidos desde que sejam usados na posição correta.

O exemplo a seguir funciona corretamente porque: o parâmetro productName é explicitamente nomeado, não é seguido por argumentos posicionais e está na posição correta.


PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");

Argumentos posicionais que seguem argumentos nomeados fora de ordem são inválidos.


// This generates CS1738: Named argument specifications must appear after all fixed arguments have been specified.
PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");

Argumentos opcionais

Uma definição de método pode especificar se seus parâmetros são necessários ou opcionais. Qualquer chamada deve fornecer argumentos para todos os parâmetros necessários, mas pode omitir argumentos para parâmetros opcionais. Um tipo de referência anulável (T?) permite que os argumentos sejam explicitamente null mas não tornam inerentemente um parâmetro opcional.

Cada parâmetro opcional tem um valor padrão como parte de sua definição. Se nenhum argumento for enviado para esse parâmetro, o valor padrão será usado. Um valor padrão deve ser um dos seguintes tipos de expressões:

  • Uma expressão constante, como uma cadeia de caracteres literal ou um número.
  • Uma expressão do formulário new ValType(), em que ValType é um tipo de valor, como um enum ou um struct.
  • Uma expressão do formulário default(ValType), em que ValType é um tipo de valor.

Os parâmetros opcionais são definidos no final da lista de parâmetros, após todos os parâmetros necessários. O chamador deve fornecer argumentos para todos os parâmetros necessários e quaisquer parâmetros opcionais anteriores aos especificados por ele. Não há suporte para lacunas separadas por vírgulas na lista de argumentos. Por exemplo, no código a seguir, o método de instância ExampleMethod é definido com um parâmetro obrigatório e dois opcionais.


public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10)

A chamada a seguir para ExampleMethod causa um erro do compilador, porque um argumento é fornecido para o terceiro parâmetro, mas não para o segundo.


// anExample.ExampleMethod(3, ,4);

No entanto, se você souber o nome do terceiro parâmetro, poderá usar um argumento nomeado para realizar a tarefa.


anExample.ExampleMethod(3, optionalint: 4);

O IntelliSense usa colchetes para indicar parâmetros opcionais, conforme mostrado na ilustração a seguir:

Captura de tela mostrando como o IntelliSence usa colchetes para indicar parâmetros opcionais.

Nota

Você também pode declarar parâmetros opcionais usando a classe de OptionalAttribute .NET. OptionalAttribute parâmetros não exigem um valor padrão. No entanto, se um valor padrão for desejado, considere usar a classe DefaultParameterValueAttribute.

No exemplo a seguir, o construtor para ExampleClass tem um parâmetro, que é opcional. O método de instância ExampleMethod tem um parâmetro necessário, requirede dois parâmetros opcionais, optionalstr e optionalint. O código em Main mostra as diferentes maneiras pelas quais o construtor e o método podem ser invocados.


namespace OptionalNamespace
{
    class OptionalExample
    {
        static void Main(string[] args)
        {
            // Instance anExample does not send an argument for the constructor's
            // optional parameter.
            ExampleClass anExample = new ExampleClass();
            anExample.ExampleMethod(1, "One", 1);
            anExample.ExampleMethod(2, "Two");
            anExample.ExampleMethod(3);

            // Instance anotherExample sends an argument for the constructor's
            // optional parameter.
            ExampleClass anotherExample = new ExampleClass("Provided name");
            anotherExample.ExampleMethod(1, "One", 1);
            anotherExample.ExampleMethod(2, "Two");
            anotherExample.ExampleMethod(3);

            // The following statements produce compiler errors.

            // An argument must be supplied for the first parameter, and it
            // must be an integer.
            //anExample.ExampleMethod("One", 1);
            //anExample.ExampleMethod();

            // You can't leave a gap in the provided arguments.
            //anExample.ExampleMethod(3, ,4);
            //anExample.ExampleMethod(3, 4);

            // You can use a named parameter to make the previous
            // statement work.
            anExample.ExampleMethod(3, optionalint: 4);
        }
    }

    class ExampleClass
    {
        private string _name;

        // Because the parameter for the constructor, name, has a default
        // value assigned to it, it's optional.
        public ExampleClass(string name = "Default name")
        {
            _name = name;
        }

        // The first parameter, required, has no default value assigned
        // to it. Therefore, it isn't optional. Both optionalstr and
        // optionalint have default values assigned to them. They're optional.
        public void ExampleMethod(int required, string optionalstr = "default string",
            int optionalint = 10)
        {
            Console.WriteLine(
                $"{_name}: {required}, {optionalstr}, and {optionalint}.");
        }
    }

    // The output from this example is the following:
    // Default name: 1, One, and 1.
    // Default name: 2, Two, and 10.
    // Default name: 3, default string, and 10.
    // Provided name: 1, One, and 1.
    // Provided name: 2, Two, and 10.
    // Provided name: 3, default string, and 10.
    // Default name: 3, default string, and 4.
}

Resolução de sobrecarga para argumentos nomeados e opcionais

Métodos sobrecarregados são métodos que têm o mesmo nome, mas assinaturas diferentes. A assinatura de um método consiste no nome do método e no tipo e tipo (valor, referência ou saída) de cada um de seus parâmetros formais. A resolução de sobrecarga é o processo de seleção do melhor método para chamar entre vários métodos que têm o mesmo nome, mas assinaturas diferentes.

O uso de argumentos nomeados e opcionais afeta a resolução de sobrecarga das seguintes maneiras:

  • Um método é um candidato para execução se cada um de seus parâmetros for opcional ou corresponder, por nome ou por posição, a um único argumento na instrução de chamada e esse argumento puder ser convertido no tipo do parâmetro.
  • Se mais de um candidato for encontrado, as regras de resolução de sobrecarga para conversões preferenciais serão aplicadas aos argumentos especificados explicitamente. Os argumentos omitidos para parâmetros opcionais são ignorados.
  • Se dois candidatos forem julgados como igualmente bons, a preferência irá para um candidato que não tenha parâmetros opcionais para os quais os argumentos foram omitidos na chamada. A resolução de sobrecarga geralmente prefere candidatos com menos parâmetros.