Arguments nommés et facultatifs (Guide de programmation C#)

Les arguments nommés vous permettent de spécifier un argument pour un paramètre en faisant correspondre l’argument avec son nom plutôt qu’avec sa position dans la liste de paramètres. Les arguments facultatifs vous permettent d’omettre des arguments pour certains paramètres. Les deux techniques peuvent être utilisées avec les méthodes, les indexeurs, les constructeurs et les délégués.

Quand vous utilisez des arguments nommés et facultatifs, ils sont évalués selon leur ordre d’affichage dans la liste d’arguments, et non dans la liste de paramètres.

Les paramètres nommés et facultatifs vous permettent de fournir des arguments pour les paramètres sélectionnés. Cette fonctionnalité facilite considérablement les appels aux interfaces COM telles que les API Microsoft Office Automation.

Arguments nommés

Avec les arguments nommés, vous n’avez plus à faire correspondre l’ordre des arguments avec l’ordre des paramètres dans les listes de paramètres des méthodes appelées. L’argument pour chaque paramètre peut être spécifié par le nom du paramètre. Par exemple, une fonction qui imprime les détails d’une commande (par exemple, le nom du vendeur, le nom du produit et le numéro de commande) peut être appelée en envoyant des arguments par position, dans l’ordre défini par la fonction.

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

Si vous ne vous souvenez pas de l’ordre des paramètres, mais que vous connaissez leur nom, vous pouvez envoyer les arguments dans n’importe quel ordre.

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

Les arguments nommés améliorent également la lisibilité de votre code en identifiant ce que chaque argument représente. Dans l’exemple de méthode ci-dessous, sellerName ne peut pas être une valeur Null ou un espace blanc. sellerName et productName étant tous deux des types de chaînes, au lieu d’envoyer les arguments par position, il est plus logique d’utiliser des arguments nommés pour lever l’ambiguïté entre les deux et réduire les risques de confusion pour toute personne lisant le code.

Les arguments nommés, quand ils sont utilisés avec des arguments de position, sont valides tant que :

  • Ils ne sont pas suivis d’arguments de position, ou

    PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
    
  • ils sont utilisés dans la position correcte. Dans l’exemple ci-dessous, le paramètre orderNum est à la position correcte, mais il n’est pas explicitement nommé.

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

Les arguments positionnels qui suivent des arguments nommés dans le désordre ne sont pas valides.

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

Exemple

Le code suivant implémente les exemples de cette section, ainsi que d’autres exemples.

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"); 
        PrintOrderDetails("Gift Shop", orderNum: 31, "Red Mug");

        // 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}");
    }
}

Arguments facultatifs

La définition d’une méthode, d’un constructeur, d’un indexeur ou d’un délégué peut spécifier que ses paramètres sont obligatoires ou facultatifs. Chaque appel doit fournir des arguments pour tous les paramètres obligatoires, mais peut omettre les arguments des paramètres facultatifs.

Dans sa définition, chaque paramètre facultatif a une valeur par défaut. Si aucun argument n’est envoyé pour ce paramètre, la valeur par défaut est utilisée. Une valeur par défaut doit être l’un des types d’expressions suivants :

  • une expression constante ;
  • une expression de la forme new ValType(), où ValType est un type valeur (par exemple, enum ou struct) ;
  • une expression de la forme default(ValType), où ValType est un type valeur.

Les paramètres facultatifs sont définis à la fin de la liste de paramètres, après tous les paramètres obligatoires. Si l’appelant fournit un argument pour l’un des paramètres d’une série de paramètres facultatifs, il doit fournir des arguments pour tous les paramètres facultatifs précédents. Les intervalles séparés par des virgules ne sont pas autorisés dans la liste d’arguments. Par exemple, dans le code suivant, la méthode d’instance ExampleMethod est définie avec un paramètre obligatoire et deux paramètres facultatifs.

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

L’appel suivant à ExampleMethod provoque une erreur du compilateur, car un argument est fourni pour le troisième paramètre, mais pas pour le deuxième.

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

Toutefois, si vous connaissez le nom du troisième paramètre, vous pouvez utiliser un argument nommé pour effectuer la tâche.

anExample.ExampleMethod(3, optionalint: 4);

IntelliSense indique les paramètres facultatifs par des crochets, comme illustré dans l’exemple suivant :

Screenshot showing IntelliSense quick info for the ExampleMethod method.

Remarque

Vous pouvez aussi déclarer des paramètres facultatifs à l’aide de la classe OptionalAttribute .NET. Les paramètres OptionalAttribute ne nécessitent pas de valeur par défaut. Toutefois, si une valeur par défaut est souhaitée, examinez la classe DefaultParameterValueAttribute.

Exemple

Dans l’exemple suivant, le constructeur associé à ExampleClass a un seul paramètre, qui est facultatif. La méthode d’instance ExampleMethod a un paramètre obligatoire (required) et deux paramètres facultatifs (optionalstr et optionalint). Le code dans Main montre les différentes façons dont le constructeur et la méthode peuvent être appelés.

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.
}

Le code précédent montre un certain nombre d’exemples où les paramètres facultatifs ne sont pas appliqués correctement. Le premier montre qu’un argument doit être fourni pour le premier paramètre, qui est obligatoire.

interfaces COM

Avec la prise en charge des objets dynamiques, les arguments nommés et facultatifs améliorent grandement l’interopérabilité avec les API COM telles que les API Office Automation.

Par exemple, la méthode AutoFormat de l’interface Range de Microsoft Office Excel comporte sept paramètres, tous facultatifs. Ces paramètres sont indiqués dans l’illustration suivante :

Screenshot showing IntelliSense quick info for the AutoFormat method.

Toutefois, vous pouvez considérablement simplifier l’appel à AutoFormat en utilisant les arguments nommés et facultatifs. Les arguments nommés et facultatifs vous permettent d’omettre l’argument d’un paramètre facultatif si vous ne souhaitez pas changer la valeur par défaut du paramètre. Dans l’appel suivant, une valeur est spécifiée pour un seul des sept paramètres.

var excelApp = new Microsoft.Office.Interop.Excel.Application();
excelApp.Workbooks.Add();
excelApp.Visible = true;

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

excelApp.Range["A1", "B4"].AutoFormat( Format: myFormat );

Pour obtenir plus d’informations et des exemples, consultez Guide pratique pour utiliser des arguments nommés et facultatifs dans la programmation Office et Guide pratique pour accéder aux objets Office Interop à l’aide des fonctionnalités C#.

Résolution de surcharge

L’utilisation d’arguments nommés et facultatifs affecte la résolution de surcharge des manières suivantes :

  • Une méthode, un indexeur ou un constructeur est un candidat pour l’exécution si chacun de ses paramètres est facultatif ou correspond, par nom ou par position, à un seul argument dans l’instruction appelante, et que cet argument peut être converti vers le type du paramètre.
  • Si plusieurs candidats sont trouvés, les règles de résolution de surcharge des conversions préférées sont appliquées aux arguments qui sont explicitement spécifiés. Les arguments omis pour les paramètres facultatifs sont ignorés.
  • Si deux candidats sont jugés de qualité équivalente, la préférence va à celui qui n’a pas de paramètres facultatifs pour lesquels des arguments ont été omis dans l’appel. La résolution de surcharges préfère généralement les candidats qui ont moins de paramètres.

spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.