Argomenti denominati e facoltativi (Guida per programmatori C#)Named and Optional Arguments (C# Programming Guide)

In C# 4 sono stati introdotti gli argomenti denominati e facoltativi.C# 4 introduces named and optional arguments. Gli argomenti denominati consentono di specificare un argomento per un parametro eseguendo la corrispondenza dell'argomento con il relativo nome invece che con la relativa posizione nell'elenco di parametri.Named arguments enable you to specify an argument for a parameter by matching the argument with its name rather than with its position in the parameter list. Gli argomenti facoltativi consentono di omettere gli argomenti per alcuni parametri.Optional arguments enable you to omit arguments for some parameters. Entrambe le tecniche possono essere usate con i metodi, gli indicizzatori, i costruttori e i delegati.Both techniques can be used with methods, indexers, constructors, and delegates.

Quando si usano gli argomenti denominati e facoltativi, gli argomenti vengono valutati nell'ordine nel quale sono visualizzati nell'elenco di argomenti, non nell'elenco di parametri.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.

I parametri denominati e facoltativi consentono di fornire argomenti per i parametri selezionati.Named and optional parameters enable you to supply arguments for selected parameters. Questa funzionalità semplifica significativamente le chiamate a interfacce COM, ad esempio le API di automazione del Microsoft Office.This capability greatly eases calls to COM interfaces such as the Microsoft Office Automation APIs.

Argomenti denominatiNamed Arguments

Gli argomenti denominati non consentono di abbinare l'ordine dei parametri negli elenchi di parametri dei metodi chiamati.Named arguments free you from matching the order of parameters in the parameter lists of called methods. Il parametro per ogni argomento può essere specificato dal nome del parametro.The parameter for each argument can be specified by parameter name. Ad esempio, una funzione che stampa i dettagli dell'ordine, ad esempio il nome del venditore, il numero dell'ordine & il nome del prodotto, può essere chiamato inviando argomenti in base alla posizione, nell'ordine definito dalla funzione.For example, a function that prints order details (such as, seller name, order number & product name) can be called by sending arguments by position, in the order defined by the function.

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

Se non si ricorda l'ordine dei parametri ma si conoscono i nomi, è possibile inviare gli argomenti in qualsiasi ordine.If you don't 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);

Gli argomenti denominati migliorano anche la leggibilità del codice identificando che cosa rappresenta ogni argomento.Named arguments also improve the readability of your code by identifying what each argument represents. Nel metodo di esempio riportato di seguito, sellerName non può essere null o uno spazio vuoto.In the example method below, the sellerName can't be null or white space. sellerName e productName sono di tipi stringa, quindi, anziché inviare argomenti in base alla posizione, è opportuno usare argomenti denominati per evitare ambiguità tra i due e semplificare la lettura del codice.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.

Se usati con argomenti posizionali, gli argomenti denominati sono validi seNamed arguments, when used with positional arguments, are valid as long as

  • non sono seguiti da argomenti posizionali, othey're not followed by any positional arguments, or

    PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
    
  • iniziando con C# 7.2, vengono usati nella posizione corretta.starting with C# 7.2, they're used in the correct position. Nell'esempio seguente il parametro orderNum è nella posizione corretta, ma non è denominato in modo esplicito.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");
    

Gli argomenti posizionali che seguono gli argomenti denominati non ordinati non sono validi.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");

EsempioExample

Il codice seguente implementa gli esempi di questa e altre sezioni.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}");
    }
}

Argomenti facoltativiOptional Arguments

La definizione di un metodo, un costruttore, un indicizzatore o un delegato può specificare che i parametri sono obbligatori o facoltativi.The definition of a method, constructor, indexer, or delegate can specify its parameters are required or optional. Tutte le chiamate devono specificare gli argomenti per tutti i parametri obbligatori, ma possono omettere gli argomenti per i parametri facoltativi.Any call must provide arguments for all required parameters, but can omit arguments for optional parameters.

Ogni parametro facoltativo ha un valore predefinito incluso nella definizione.Each optional parameter has a default value as part of its definition. Se per il parametro non viene inviato alcun argomento, viene usato il valore predefinito.If no argument is sent for that parameter, the default value is used. Il valore predefinito deve essere uno dei tipi di espressioni seguenti:A default value must be one of the following types of expressions:

  • un'espressione costante;a constant expression;
  • un'espressione del form new ValType(), dove ValType è un tipo di valore, ad esempio enum o struct;an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;
  • un'espressione del form default(ValType), dove ValType è un tipo di valore.an expression of the form default(ValType), where ValType is a value type.

I parametri facoltativi sono definiti alla fine dell'elenco di parametri, dopo eventuali parametri obbligatori.Optional parameters are defined at the end of the parameter list, after any required parameters. Se il chiamante specifica un argomento per un parametro di una successione di parametri facoltativi, deve specificare gli argomenti per tutti i parametri facoltativi precedenti.If the caller provides an argument for any one of a succession of optional parameters, it must provide arguments for all preceding optional parameters. Non sono supportati i gap delimitati da virgole nell'elenco di argomenti.Comma-separated gaps in the argument list aren't supported. Nel codice seguente, ad esempio, il metodo di istanza ExampleMethod viene definito con un parametro obbligatorio e due parametri facoltativi.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 chiamata seguente a ExampleMethod genera un errore del compilatore, poiché viene specificato un argomento per il terzo parametro ma non per il secondo.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);

Se, tuttavia, si conosce il nome del terzo parametro, è possibile usare un argomento denominato per eseguire l'attività.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);

IntelliSense usa le parentesi per indicare parametri facoltativi, come illustrato nell'immagine seguente:IntelliSense uses brackets to indicate optional parameters, as shown in the following illustration:

Screenshot con le informazioni rapide di IntelliSense per il metodo ExampleMethod.

Nota

È possibile anche dichiarare parametri facoltativi usando la classe .NET OptionalAttribute.You can also declare optional parameters by using the .NET OptionalAttribute class. I parametri OptionalAttribute non richiedono un valore predefinito.OptionalAttribute parameters do not require a default value.

EsempioExample

Nell'esempio seguente il costruttore per ExampleClass ha un solo parametro facoltativo.In the following example, the constructor for ExampleClass has one parameter, which is optional. Il metodo di istanza ExampleMethod ha un solo parametro obbligatorio, required, e due parametri facoltativi, optionalstr e optionalint.Instance method ExampleMethod has one required parameter, required, and two optional parameters, optionalstr and optionalint. Il codice in Main illustra i diversi modi in cui è possibile richiamare il costruttore e il metodo.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(
                $"{_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.
}

Il codice precedente mostra alcuni esempi in cui i parametri facoltativi non vengono applicati correttamente.The preceding code shows a number of examples where optional parameters aren't applied correctly. Il primo illustra che è necessario specificare un argomento per il primo parametro, che è obbligatorio.The first illustrates that an argument must be supplied for the first parameter, which is required.

Interfacce COMCOM Interfaces

Gli argomenti denominati e facoltativi, oltre al supporto per oggetti dinamici, migliorano significativamente l'interoperabilità con le API COM, ad esempio le API di automazione di Office.Named and optional arguments, along with support for dynamic objects, greatly improve interoperability with COM APIs, such as Office Automation APIs.

Ad esempio, il metodo AutoFormat nell'interfaccia Range di Microsoft Office Excel ha sette parametri facoltativi.For example, the AutoFormat method in the Microsoft Office Excel Range interface has seven parameters, all of which are optional. Questi parametri sono illustrati nell'immagine seguente:These parameters are shown in the following illustration:

Screenshot con le informazioni rapide di IntelliSense per il metodo AutoFormat.

In C# 3.0 e versioni precedenti è necessario un argomento per ogni parametro, come illustrato nell'esempio seguente.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);

È tuttavia possibile semplificare in modo sostanziale la chiamata a AutoFormat mediante argomenti denominati e facoltativi, introdotti in C# 4.0.However, you can greatly simplify the call to AutoFormat by using named and optional arguments, introduced in C# 4.0. Gli argomenti denominati e facoltativi consentono di omettere l'argomento per un parametro facoltativo se non si vuole modificare il valore predefinito del parametro.Named and optional arguments enable you to omit the argument for an optional parameter if you don't want to change the parameter's default value. Nella chiamata seguente viene specificato un valore per uno solo dei sette parametri.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 );

Per altre informazioni ed esempi, vedere come usare gli argomenti denominati e facoltativi nella programmazione di Office e come accedere agli oggetti di interoperabilità di Office usando le funzionalità di 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 C# features.

Overload ResolutionOverload Resolution

L'uso di argomenti denominati e facoltativi influisce sulla risoluzione dell'overload nei modi seguenti:Use of named and optional arguments affects overload resolution in the following ways:

  • Un metodo, un indicizzatore o un costruttore è un candidato per l'esecuzione se ogni parametro è facoltativo o corrisponde, per nome o per posizione, a un solo argomento nell'istruzione chiamante e tale argomento può essere convertito nel tipo del parametro.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 è disponibile più di un candidato, agli argomenti specificati in modo esplicito vengono applicate le regole di risoluzione dell'overload per le conversioni preferite.If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Gli argomenti omessi per i parametri facoltativi vengono ignorati.Omitted arguments for optional parameters are ignored.
  • Se due candidati vengono giudicati ugualmente validi, la preferenza passa a un candidato che non dispone di parametri facoltativi per i quali gli argomenti sono stati omessi nella chiamata.If two candidates are judged to be equally good, preference goes to a candidate that doesn't have optional parameters for which arguments were omitted in the call. La risoluzione dell'overload preferisce in genere i candidati con un minor numero di parametri.Overload resolution generally prefers candidates that have fewer parameters.

Specifiche del linguaggio C#C# Language Specification

Per ulteriori informazioni, vedere la specifica del linguaggio C#.For more information, see the C# Language Specification. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.The language specification is the definitive source for C# syntax and usage.