Argumentos opcionales y con nombre (Guía de programación de C#)Named and Optional Arguments (C# Programming Guide)

C# 4 introduce argumentos opcionales y con nombre.C# 4 introduces named and optional arguments. Los argumentos con nombre permiten especificar un argumento para un parámetro concreto asociando el argumento al nombre del parámetro y no a la posición del parámetro en la 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. Los argumentos opcionales permiten omitir argumentos para algunos parámetros.Optional arguments enable you to omit arguments for some parameters. Ambas técnicas se pueden usar con métodos, indexadores, constructores y delegados.Both techniques can be used with methods, indexers, constructors, and delegates.

Cuando se usan argumentos opcionales y con nombre, los argumentos se evalúan por el orden en que aparecen en la lista de argumentos, no en la 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.

Los parámetros opcionales y con nombre, cuando se usan conjuntamente, solo permiten especificar argumentos para algunos parámetros de una lista de parámetros opcionales.Named and optional parameters, when used together, enable you to supply arguments for only a few parameters from a list of optional parameters. Esta funcionalidad facilita enormemente las llamadas a interfaces COM, como las API de automatización de Microsoft Office.This capability greatly facilitates calls to COM interfaces such as the Microsoft Office Automation APIs.

Argumentos con nombreNamed Arguments

Los argumentos con nombre le liberan de la necesidad de recordar o buscar el orden de los parámetros de la lista de parámetros de los métodos llamados.Named arguments free you from the need to remember or to look up the order of parameters in the parameter lists of called methods. El parámetro de cada argumento se puede especificar por nombre de parámetro.The parameter for each argument can be specified by parameter name. Por ejemplo, se puede llamar de la manera habitual a una función que imprime los detalles de un pedido (como por ejemplo, el nombre de vendedor, el nombre de producto y el número del pedido) mediante el envío de argumentos por posición, en el orden definido por la función.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");

Si no recuerda el orden de los parámetros pero conoce sus nombres, puede enviar los argumentos en cualquier orden.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);

Los argumentos con nombre también mejoran la legibilidad del código al identificar lo que cada argumento representa.Named arguments also improve the readability of your code by identifying what each argument represents. En el método de ejemplo siguiente, sellerName no puede ser nulo ni un espacio en blanco.In the example method below, the sellerName cannot be null or white space. Como sellerName y productName son tipos de cadena, en lugar de enviar argumentos por posición, tiene sentido usar argumentos con nombre para eliminar la ambigüedad entre ambos y evitar confusiones para aquellos que lean el 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.

Los argumentos con nombre, cuando se usan con argumentos posicionales, son válidos siempre queNamed arguments, when used with positional arguments, are valid as long as

  • no vayan seguidos de ningún argumento posicional o,they're not followed by any positional arguments, or

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

  • a partir de C# 7.2, se usen en la posición correcta.starting with C# 7.2, they're used in the correct position. En este ejemplo, el parámetro orderNum está en la posición correcta pero no se le asigna un nombre de manera explícita.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");

Sin embargo, los argumentos con nombre que no están en el orden correcto no son válidos si van seguidos de argumentos posicionales.However, out-of-order named arguments are invalid if they're followed by positional arguments.

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

EjemploExample

Con este código se implementan los ejemplos de esta sección junto con otros adicionales.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 opcionalesOptional Arguments

La definición de un método, constructor, indexador o delegado puede especificar que sus parámetros son necesarios o que son opcionales.The definition of a method, constructor, indexer, or delegate can specify that its parameters are required or that they are optional. Todas las llamadas deben proporcionar argumentos para todos los parámetros necesarios, pero pueden omitir los argumentos para los parámetros opcionales.Any call must provide arguments for all required parameters, but can omit arguments for optional parameters.

Cada parámetro opcional tiene un valor predeterminado como parte de su definición.Each optional parameter has a default value as part of its definition. Si no se envía ningún argumento para ese parámetro, se usa el valor predeterminado.If no argument is sent for that parameter, the default value is used. Un valor predeterminado debe ser uno de los siguientes tipos de expresiones:A default value must be one of the following types of expressions:

  • una expresión constante;a constant expression;

  • una expresión con el formato new ValType(), donde ValType es un tipo de valor, como enum o struct;an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;

  • una expresión con el formato default(ValType), donde ValType es un tipo de valor.an expression of the form default(ValType), where ValType is a value type.

Los parámetros opcionales se definen al final de la lista de parámetros después de los parámetros necesarios.Optional parameters are defined at the end of the parameter list, after any required parameters. Si el autor de la llamada proporciona un argumento para algún parámetro de una sucesión de parámetros opcionales, debe proporcionar argumentos para todos los parámetros opcionales 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. No se admiten espacios separados por comas en la lista de argumentos.Comma-separated gaps in the argument list are not supported. Por ejemplo, en el código siguiente, el método de instancia ExampleMethod se define con un parámetro necesario y dos opcionales.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)

La llamada siguiente a ExampleMethod genera un error del compilador, porque se proporciona un argumento para el tercer parámetro pero no para el 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);

Pero si conoce el nombre del tercer parámetro, puede usar un argumento con nombre para realizar la tarea.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);

En IntelliSense los corchetes se usan para indicar parámetros opcionales, como se muestra en la ilustración siguiente:IntelliSense uses brackets to indicate optional parameters, as shown in the following illustration:

Captura de pantalla en la que se muestra información rápida de IntelliSense para el método ExampleMethod.

Nota

También puede declarar parámetros opcionales con la clase OptionalAttribute de .NET.You can also declare optional parameters by using the .NET OptionalAttribute class. Los parámetros OptionalAttribute no requieren un valor predeterminado.OptionalAttribute parameters do not require a default value.

EjemploExample

En el ejemplo siguiente, el constructor de ExampleClass tiene un solo parámetro, que es opcional.In the following example, the constructor for ExampleClass has one parameter, which is optional. El método de instancia ExampleMethod tiene un parámetro necesario, required, y dos parámetros opcionales, optionalstr y optionalint.Instance method ExampleMethod has one required parameter, required, and two optional parameters, optionalstr and optionalint. El código de Main muestra las distintas formas en que se pueden invocar el constructor y el método.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

Los argumentos opcionales y con nombre, además de compatibilidad con objetos dinámicos y otros avances, mejoran considerablemente la interoperabilidad con las API de COM, como las API de automatización de 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 ejemplo, el método AutoFormat de la interfaz Range de Microsoft Office Excel tiene siete parámetros, todos ellos opcionales.For example, the AutoFormat method in the Microsoft Office Excel Range interface has seven parameters, all of which are optional. Estos parámetros se muestran en la ilustración siguiente:These parameters are shown in the following illustration:

Captura de pantalla en la que se muestra información rápida de IntelliSense para el método AutoFormat.

En C# 3.0 y versiones anteriores, se requiere un argumento para cada parámetro, tal y como se muestra en el ejemplo siguiente.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);

Pero la llamada a AutoFormat se puede simplificar considerablemente mediante argumentos opcionales y con nombre, que se introducen en C# 4.0.However, you can greatly simplify the call to AutoFormat by using named and optional arguments, introduced in C# 4.0. Los parámetros opcionales y con nombre permiten omitir el argumento de un parámetro opcional si no se quiere cambiar el valor predeterminado del 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. En la siguiente llamada, solo se especifica un valor para uno de los siete 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 obtener más información y ejemplos, vea Cómo: Usar argumentos opcionales y con nombre en la programación de Office y Cómo: Tener acceso a objetos de interoperabilidad de Office mediante las características de Visual C#.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 Visual C# Features.

Overload ResolutionOverload Resolution

El uso de argumentos opcionales y con nombre afecta a la resolución de sobrecarga de las maneras siguientes:Use of named and optional arguments affects overload resolution in the following ways:

  • Un método, indexador o constructor es un candidato para la ejecución si cada uno de sus parámetros es opcional o corresponde, por nombre o por posición, a un solo argumento de la instrucción de llamada y el argumento se puede convertir al tipo del 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.

  • Si se encuentra más de un candidato, se aplican las reglas de resolución de sobrecarga de las conversiones preferidas a los argumentos que se especifican explícitamente.If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Los argumentos omitidos en parámetros opcionales se ignoran.Omitted arguments for optional parameters are ignored.

  • Si dos candidatos se consideran igualmente correctos, la preferencia pasa a un candidato que no tenga parámetros opcionales cuyos argumentos se hayan omitido en la llamada.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. Se trata de una consecuencia de una preferencia general en la resolución de sobrecarga para los candidatos con menos parámetros.This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

Especificación del lenguaje C#C# Language Specification

Para obtener más información, consulte la Especificación del lenguaje C#.For more information, see the C# Language Specification. La especificación del lenguaje es la fuente definitiva de la sintaxis y el uso de C#.The language specification is the definitive source for C# syntax and usage.

Vea tambiénSee also