Именованные и необязательные аргументы (Руководство по программированию на C#)Named and Optional Arguments (C# Programming Guide)

C# 4 вводит именованные и необязательные аргументы.C# 4 introduces named and optional arguments. Именованные аргументы позволяют указать аргумент для определенного параметра, связав этот аргумент с именем параметра, а не с его позицией в списке параметров.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. Необязательные аргументы позволяют опускать аргументы для некоторых параметров.Optional arguments enable you to omit arguments for some parameters. Оба варианта можно использовать с методами, индексаторами, конструкторами и делегатами.Both techniques can be used with methods, indexers, constructors, and delegates.

При использовании именованных и необязательных аргументов аргументы оцениваются в том порядке, в котором они отображаются в списке аргументов, а не в списке параметров.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.

При совместном использовании именованные и необязательные параметры позволяют задавать аргументы только для некоторых параметров из списка необязательных параметров.Named and optional parameters, when used together, enable you to supply arguments for only a few parameters from a list of optional parameters. Эта возможность значительно упрощает вызов интерфейсов COM, таких как API автоматизации Microsoft Office.This capability greatly facilitates calls to COM interfaces such as the Microsoft Office Automation APIs.

Именованные аргументыNamed Arguments

Именованные аргументы освобождают разработчика от необходимости запоминать или уточнять порядок параметров в списках параметров вызванных методов.Named arguments free you from the need to remember or to look up the order of parameters in the parameter lists of called methods. Параметр для каждого аргумента можно указать, используя имя параметра.The parameter for each argument can be specified by parameter name. Например, функция, которая выводит сведения о заказе (например, имя продавца, номер заказа и наименование товара), может вызываться как обычно, путем передачи аргументов по позиции в порядке, определяемом функцией.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");

Если вы не помните порядок параметров, но знаете их имена, можете передать аргументы в любом порядке.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);

Именованные аргументы также делают код более удобным для чтения, поскольку указывают, чему соответствует каждый аргумент.Named arguments also improve the readability of your code by identifying what each argument represents. В приведенном ниже примере метода sellerName не может быть равен NULL или пробелу.In the example method below, the sellerName cannot be null or white space. Так как и sellerName, и productName являются строковыми типами, вместо передачи аргументов по позиции имеет смысл использовать именованные аргументы, чтобы устранить данную неоднозначность и сделать код более удобочитаемым.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.

Именованные аргументы при использовании с позиционными аргументами допустимы при условии, чтоNamed arguments, when used with positional arguments, are valid as long as

  • за ними не следуют позиционные аргументы, либо,they're not followed by any positional arguments, or

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

  • начиная с C# 7.2, они используются в правильной позиции.starting with C# 7.2, they're used in the correct position. В примере ниже параметр orderNum находится в правильной позиции, но не имеет явно заданного имени.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");

Позиционные аргументы после внеочередных именованных аргументов недопустимы.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");

ПримерExample

Приведенный ниже код реализует как примеры из этого раздела, так и некоторые дополнительные примеры.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}");
    }
}

Необязательные аргументыOptional Arguments

Определение метода, конструктора, индексатора или делегата может указывать, являются его параметры обязательными или нет.The definition of a method, constructor, indexer, or delegate can specify that its parameters are required or that they are optional. Любой вызов должен содержать аргументы для всех обязательных параметров; аргументы для необязательных параметров можно опустить.Any call must provide arguments for all required parameters, but can omit arguments for optional parameters.

Определение каждого необязательного параметра содержит его значение по умолчанию.Each optional parameter has a default value as part of its definition. Если аргумент для параметра не передается, используется значение по умолчанию.If no argument is sent for that parameter, the default value is used. Значением по умолчанию должен быть один из следующих типов выражений:A default value must be one of the following types of expressions:

  • константное выражение;a constant expression;

  • выражение в форме new ValType(), где ValType — это тип значения, например, enum или struct;an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;

  • выражение в форме default(ValType), где ValType — это тип значения.an expression of the form default(ValType), where ValType is a value type.

Необязательные параметры определяются в конце списка параметров после всех обязательных параметров.Optional parameters are defined at the end of the parameter list, after any required parameters. Если вызывающий объект предоставляет аргумент для любого из последующих необязательных параметров, он должен содержать аргументы для всех предыдущих необязательных параметров.If the caller provides an argument for any one of a succession of optional parameters, it must provide arguments for all preceding optional parameters. Пробелы, разделенные запятыми, в списке аргументов не поддерживаются.Comma-separated gaps in the argument list are not supported. Например, в следующем коде метод экземпляра ExampleMethod определяется одним обязательным и двумя необязательными параметрами.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)

Следующий вызов ExampleMethod вызывает ошибку компилятора, поскольку аргумент предоставляется для третьего параметра, но не для второго.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);

Если вы знаете имя третьего параметра, можете использовать для выполнения задачи именованный аргумент.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 необязательные параметры заключаются в квадратные скобки, как показано на следующем рисунке:IntelliSense uses brackets to indicate optional parameters, as shown in the following illustration:

Снимок экрана, показывающий краткие сведения IntelliSense для метода ExampleMethod.

Примечание

Необязательные параметры также можно объявлять с помощью класса .NET OptionalAttribute.You can also declare optional parameters by using the .NET OptionalAttribute class. Для параметров OptionalAttribute значение по умолчанию не требуется.OptionalAttribute parameters do not require a default value.

ПримерExample

В следующем примере конструктор ExampleClass имеет один параметр, который является необязательным.In the following example, the constructor for ExampleClass has one parameter, which is optional. У метода экземпляра ExampleMethod есть один обязательный параметр, required, и два необязательных параметра, optionalstr и optionalint.Instance method ExampleMethod has one required parameter, required, and two optional parameters, optionalstr and optionalint. Код в Main демонстрирует различные способы, которые можно использовать для вызова конструктора и метода.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.

}

Интерфейсы COMCOM Interfaces

Именованные и необязательные аргументы, а также поддержка динамических объектов и другие усовершенствования значительно улучшают взаимодействие с API COM, такими как API автоматизации 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.

Например, метод AutoFormatв интерфейсе Microsoft Office Excel Range имеет семь параметров и все они необязательные.For example, the AutoFormat method in the Microsoft Office Excel Range interface has seven parameters, all of which are optional. Эти параметры показаны на следующем рисунке:These parameters are shown in the following illustration:

Снимок экрана, показывающий краткие сведения IntelliSense для метода AutoFormat.

В C# 3.0 и более ранних версиях аргумент необходимо указывать для каждого параметра, как показано в следующем примере.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);

При этом вызов AutoFormat можно значительно упростить, используя именованные и необязательные аргументы, представленные в C# 4.0.However, you can greatly simplify the call to AutoFormat by using named and optional arguments, introduced in C# 4.0. Именованные и необязательные аргументы позволяют опускать аргументы для необязательных параметров, если значение параметра по умолчанию менять не нужно.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. В следующем вызове значение задается только для одного из семи параметров.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 );

Дополнительные сведения и примеры см. в статьях Практическое руководство. Использование именованных и необязательных аргументов в программировании Office и Практическое руководство. Доступ к объектам взаимодействия Office с помощью функций 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

Использование именованных и необязательных аргументов влияет на разрешение перегрузки описанным ниже образом.Use of named and optional arguments affects overload resolution in the following ways:

  • Метод, индексатор или конструктор является кандидатом на выполнение, если каждый из его параметров необязателен либо по имени или позиции соответствует одному и тому же аргументу в операторе вызова, и этот аргумент можно преобразовать в тип параметра.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.

  • Если найдено более одного кандидата, правила разрешения перегрузки для предпочтительных преобразований применяются к аргументам, указанным явно.If more than one candidate is found, overload resolution rules for preferred conversions are applied to the arguments that are explicitly specified. Опущенные аргументы для необязательных параметров игнорируются.Omitted arguments for optional parameters are ignored.

  • Если два кандидата определяются как равно подходящие, предпочтение отдается кандидату без необязательных параметров, аргументы которых в вызове были опущены.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. Это — последовательность определения приоритетов в разрешении перегрузки для кандидатов с меньшим числом параметров.This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

Спецификация языка C#C# Language Specification

Дополнительные сведения см. в спецификации языка C#.For more information, see the C# Language Specification. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.The language specification is the definitive source for C# syntax and usage.

См. такжеSee also