Argumentos nomeados e opcionais (Guia de Programação em C#)Named and Optional Arguments (C# Programming Guide)

O C# 4 apresenta argumentos nomeados e opcionais.C# 4 introduces named and optional arguments. Argumentos nomeados permitem especificar um argumento para um parâmetro específico associando o argumento ao nome do parâmetro e não com à posição do parâmetro na lista de parâmetros.Named arguments enable you to specify an argument for a particular parameter by associating the argument with the parameter's name rather than with the parameter's position in the parameter list. Argumentos opcionais permitem omitir argumentos para alguns parâmetros.Optional arguments enable you to omit arguments for some parameters. Ambas as técnicas podem ser usadas com os métodos, indexadores, construtores e delegados.Both techniques can be used with methods, indexers, constructors, and delegates.

Quando você usa argumentos nomeados e opcionais, os argumentos são avaliados na ordem em que aparecem na lista de argumentos e não na lista de parâmetros.When you use named and optional arguments, the arguments are evaluated in the order in which they appear in the argument list, not the parameter list.

Os parâmetros nomeados e opcionais, quando usados em conjunto, permitem que você forneça argumentos para apenas alguns parâmetros de uma lista de parâmetros opcionais.Named and optional parameters, when used together, enable you to supply arguments for only a few parameters from a list of optional parameters. Essa capacidade facilita bastante a chamadas para interfaces COM como as APIs de Automação do Microsoft Office.This capability greatly facilitates calls to COM interfaces such as the Microsoft Office Automation APIs.

Argumentos nomeadosNamed Arguments

Os argumentos nomeados liberam você da necessidade de lembrar ou procurar a ordem dos parâmetros nas listas de parâmetros de métodos chamados.Named arguments free you from the need to remember or to look up the order of parameters in the parameter lists of called methods. O parâmetro para cada argumento pode ser especificado pelo nome do parâmetro.The parameter for each argument can be specified by parameter name. Por exemplo, uma função que imprime detalhes de pedidos (como o nome do vendedor, nome do produto e número do pedido) pode ser chamada da maneira padrão, por meio do envio de argumentos por posição, na ordem definida pela função.For example, a function that prints order details (such as, seller name, order number & product name) can be called in the standard way by sending arguments by position, in the order defined by the function.

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

Se não se lembrar da ordem dos parâmetros, mas souber os nomes, você poderá enviar os argumentos em qualquer ordem.If you do not remember the order of the parameters but know their names, you can send the arguments in any order.

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

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

Os argumentos nomeados também melhoram a legibilidade do código identificando o que cada argumento representa.Named arguments also improve the readability of your code by identifying what each argument represents. No método de exemplo abaixo, o sellerName não pode ser nulo ou um espaço em branco.In the example method below, the sellerName cannot be null or white space. Como sellerName e productName são tipos de cadeia de caracteres, em vez de enviar argumentos por posição, é melhor usar argumentos nomeados para remover a ambiguidade dos dois e reduzir a confusão para qualquer pessoa que leia o código.As both sellerName and productName are string types, instead of sending arguments by position, it makes sense to use named arguments to disambiguate the two and reduce confusion for anyone reading the code.

Os argumentos nomeados, quando usados com argumentos posicionais, são válidos, desde queNamed arguments, when used with positional arguments, are valid as long as

  • não sejam seguidos por argumentos posicionais ou,they're not followed by any positional arguments, or

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

  • começando com o C# 7.2, sejam usados na posição correta.starting with C# 7.2, they're used in the correct position. No exemplo a seguir, o parâmetro orderNum está na posição correta, mas não está explicitamente nomeado.In the example below, the parameter orderNum is in the correct position but isn't explicitly named.

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

Argumentos posicionais que seguem os argumentos nomeados fora de ordem são inválidos.Positional arguments that follow any out-of-order named arguments are invalid.

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

ExemploExample

O código a seguir implementa os exemplos desta seção, juntamente com outros exemplos.The following code implements the examples from this section along with some additional ones.

class NamedExample
{
    static void Main(string[] args)
    {
        // The method can be called in the normal way, by using positional arguments.
        PrintOrderDetails("Gift Shop", 31, "Red Mug");

        // Named arguments can be supplied for the parameters in any order.
        PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
        PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);

        // Named arguments mixed with positional arguments are valid
        // as long as they are used in their correct position.
        PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
        PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug");    // C# 7.2 onwards
        PrintOrderDetails("Gift Shop", orderNum: 31, "Red Mug");                   // C# 7.2 onwards

        // However, mixed arguments are invalid if used out-of-order.
        // The following statements will cause a compiler error.
        // PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
        // PrintOrderDetails(31, sellerName: "Gift Shop", "Red Mug");
        // PrintOrderDetails(31, "Red Mug", sellerName: "Gift Shop");
    }

    static void PrintOrderDetails(string sellerName, int orderNum, string productName)
    {
        if (string.IsNullOrWhiteSpace(sellerName))
        {
            throw new ArgumentException(message: "Seller name cannot be null or empty.", paramName: nameof(sellerName));
        }

        Console.WriteLine($"Seller: {sellerName}, Order #: {orderNum}, Product: {productName}");
    }
}

Argumentos opcionaisOptional Arguments

A definição de um método, construtor, indexador ou delegado pode especificar que seus parâmetros são obrigatórios ou que são opcionais.The definition of a method, constructor, indexer, or delegate can specify that its parameters are required or that they are optional. Qualquer chamada deve fornecer argumentos para todos os parâmetros necessários, mas pode omitir argumentos para parâmetros opcionais.Any call must provide arguments for all required parameters, but can omit arguments for optional parameters.

Cada parâmetro opcional tem um valor padrão como parte de sua definição.Each optional parameter has a default value as part of its definition. Se nenhum argumento é enviado para esse parâmetro, o valor padrão é usado.If no argument is sent for that parameter, the default value is used. Um valor padrão deve ser um dos seguintes tipos de expressões:A default value must be one of the following types of expressions:

  • uma expressão de constante;a constant expression;

  • uma expressão da forma new ValType(), em que ValType é um tipo de valor, como um enum ou um struct;an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;

  • uma expressão da forma default(ValType), em que ValType é um tipo de valor.an expression of the form default(ValType), where ValType is a value type.

Os parâmetros opcionais são definidos no final da lista de parâmetros, depois de todos os parâmetros obrigatórios.Optional parameters are defined at the end of the parameter list, after any required parameters. Se o chamador fornecer um argumento para qualquer um de uma sucessão de parâmetros opcionais, ele deverá fornecer argumentos para todos os parâmetros opcionais anteriores.If the caller provides an argument for any one of a succession of optional parameters, it must provide arguments for all preceding optional parameters. Não há suporte para intervalos separados por vírgula na lista de argumentos.Comma-separated gaps in the argument list are not supported. Por exemplo, no código a seguir, método de instância ExampleMethod está definido com um parâmetro obrigatório e dois opcionais.For example, in the following code, instance method ExampleMethod is defined with one required and two optional parameters.

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

A chamada para ExampleMethod a seguir causa um erro do compilador, porque um argumento é fornecido para o terceiro parâmetro, mas não para o segundo.The following call to ExampleMethod causes a compiler error, because an argument is provided for the third parameter but not for the second.

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

No entanto, se você souber o nome do terceiro parâmetro, poderá usar um argumento nomeado para realizar a tarefa.However, if you know the name of the third parameter, you can use a named argument to accomplish the task.

anExample.ExampleMethod(3, optionalint: 4);

O IntelliSense usa colchetes para indicar parâmetros opcionais, conforme mostrado na seguinte ilustração:IntelliSense uses brackets to indicate optional parameters, as shown in the following illustration:

Captura de tela mostrando as Informações Rápidas do IntelliSense para o método ExampleMethod.

Observação

Você também pode declarar parâmetros opcionais usando a classe OptionalAttribute do .NET.You can also declare optional parameters by using the .NET OptionalAttribute class. Os parâmetros OptionalAttribute não exigem um valor padrão.OptionalAttribute parameters do not require a default value.

ExemploExample

No exemplo a seguir, o construtor para ExampleClass tem um parâmetro, que é opcional.In the following example, the constructor for ExampleClass has one parameter, which is optional. O método de instância ExampleMethod tem um parâmetro obrigatório, required e dois parâmetros opcionais, optionalstr e optionalint.Instance method ExampleMethod has one required parameter, required, and two optional parameters, optionalstr and optionalint. O código em Main mostra as diferentes maneiras em que o construtor e o método podem ser invocados.The code in Main shows the different ways in which the constructor and method can be invoked.

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 cannot 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 is optional.
        public ExampleClass(string name = "Default name")
        {
            _name = name;
        }

        // The first parameter, required, has no default value assigned
        // to it. Therefore, it is not optional. Both optionalstr and 
        // optionalint have default values assigned to them. They are optional.
        public void ExampleMethod(int required, string optionalstr = "default string",
            int optionalint = 10)
        {
            Console.WriteLine("{0}: {1}, {2}, and {3}.", _name, required, optionalstr,
                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.

}

Interfaces COMCOM Interfaces

Os argumentos nomeados e opcionais, juntamente com suporte para objetos dinâmicos e outros aprimoramentos, aprimoram enormemente a interoperabilidade com APIs COM, como APIs de Automação do Office.Named and optional arguments, along with support for dynamic objects and other enhancements, greatly improve interoperability with COM APIs, such as Office Automation APIs.

Por exemplo, o método AutoFormat na interface Range do Microsoft Office Excel tem sete parâmetros, todos opcionais.For example, the AutoFormat method in the Microsoft Office Excel Range interface has seven parameters, all of which are optional. Esses parâmetros são mostrados na seguinte ilustração:These parameters are shown in the following illustration:

Captura de tela mostrando as Informações Rápidas do IntelliSense para o método AutoFormat.

No C# 3.0 e versões anteriores, é necessário um argumento para cada parâmetro, como mostrado no exemplo a seguir.In C# 3.0 and earlier versions, an argument is required for each parameter, as shown in the following example.

// In C# 3.0 and earlier versions, you need to supply an argument for
// every parameter. The following call specifies a value for the first
// parameter, and sends a placeholder value for the other six. The
// default values are used for those parameters.
var excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Workbooks.Add();
excelApp.Visible = true;

var myFormat = 
    Microsoft.Office.Interop.Excel.XlRangeAutoFormat.xlRangeAutoFormatAccounting1;

excelApp.get_Range("A1", "B4").AutoFormat(myFormat, Type.Missing, 
    Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

No entanto, você pode simplificar muito a chamada para AutoFormat usando argumentos nomeados e opcionais, introduzidos no C# 4.0.However, you can greatly simplify the call to AutoFormat by using named and optional arguments, introduced in C# 4.0. Os argumentos nomeados e opcionais permitem que você omita o argumento para um parâmetro opcional se não desejar alterar o valor padrão do parâmetro.Named and optional arguments enable you to omit the argument for an optional parameter if you do not want to change the parameter's default value. Na chamada a seguir, um valor é especificado para apenas um dos sete parâmetros.In the following call, a value is specified for only one of the seven parameters.

// The following code shows the same call to AutoFormat in C# 4.0. Only
// the argument for which you want to provide a specific value is listed.
excelApp.Range["A1", "B4"].AutoFormat( Format: myFormat );

Para obter mais informações e exemplos, consulte como usar argumentos nomeados e opcionais na programação do Office e como acessar objetos de interoperabilidade do Office usando C# recursos.For more information and examples, see How to use named and optional arguments in Office programming and How to access Office interop objects by using C# features.

Resolução de sobrecargaOverload Resolution

O uso de argumentos nomeados e opcionais afeta a resolução de sobrecarga das seguintes maneiras:Use of named and optional arguments affects overload resolution in the following ways:

  • Um método, indexador ou construtor é um candidato para a execução se cada um dos parâmetros é opcional ou corresponde, por nome ou posição, a um único argumento na instrução de chamada e esse argumento pode ser convertido para o tipo do parâmetro.A method, indexer, or constructor is a candidate for execution if each of its parameters either is optional or corresponds, by name or by position, to a single argument in the calling statement, and that argument can be converted to the type of the parameter.

  • Se mais de um candidato for encontrado, as regras de resolução de sobrecarga de conversões preferenciais serão aplicadas aos argumentos que são especificados explicitamente.If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Os argumentos omitidos para parâmetros opcionais são ignorados.Omitted arguments for optional parameters are ignored.

  • Se dois candidatos são considerados igualmente bons, a preferência vai para um candidato que não tem parâmetros opcionais para os quais argumentos foram omitidos na chamada.If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. Esta é uma consequência da preferência geral na resolução de sobrecarga de candidatos que têm menos parâmetros.This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

Especificação da linguagem C#C# Language Specification

Para obter mais informações, consulte a Especificação da linguagem C#.For more information, see the C# Language Specification. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.The language specification is the definitive source for C# syntax and usage.

Veja tambémSee also