Поделиться через


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

В Visual C# 2010 появились именованные и необязательные аргументы. Именованные аргументы позволяют указать аргумент для определенного параметра, связав аргумент с именем параметра, а не с позицией параметра в списке параметров. Необязательные аргументы позволяют опускать аргументы для некоторых параметров. Оба подхода можно применять к методам, индексаторам, конструкторам и делегатам.

При использовании именованных и необязательных аргументов аргументы вычисляются в том порядке, в котором они указаны в списке аргументов, а не в списке параметров.

При совместном использовании именованных и необязательных параметров разработчик может задавать аргументы лишь для некоторых параметров из списка необязательных параметров. Эта возможность значительно упрощает вызов интерфейсов COM, например интерфейсов API автоматизации Microsoft Office.

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

Именованные аргументы освобождают разработчика от необходимости помнить или уточнять порядок следования параметров при вызове методов. Параметр для каждого из аргументов можно задать с помощью имени параметра. Например, функцию, которая вычисляет индекс массы тела, можно вызвать обычным способом, путем передачи аргументов для веса и роста по их позиции в том порядке, в котором они заданы в определении функции.

CalculateBMI(123, 64);

Если разработчик не помнит порядок параметров, но знает их имена, он может передать аргументы в любом порядке, сначала указав вес или рост.

CalculateBMI(weight: 123, height: 64);

CalculateBMI(height: 64, weight: 123);

Кроме того, именованные аргументы упрощают восприятие кода, поскольку они указывают назначение того или иного аргумента.

Именованный аргумент можно поместить после позиционных аргументов, как показано ниже.

CalculateBMI(123, height: 64);

Однако позиционные аргументы нельзя размещать после именованных аргументов. Следующая инструкция вызывает ошибку компилятора.

//CalculateBMI(weight: 123, 64);

Пример

В следующем коде реализовано несколько примеров данного раздела.

class NamedExample
{
    static void Main(string[] args)
    {
        // The method can be called in the normal way, by using positional arguments.
        Console.WriteLine(CalculateBMI(123, 64));

        // Named arguments can be supplied for the parameters in either order.
        Console.WriteLine(CalculateBMI(weight: 123, height: 64));
        Console.WriteLine(CalculateBMI(height: 64, weight: 123));

        // Positional arguments cannot follow named arguments. 
        // The following statement causes a compiler error. 
        //Console.WriteLine(CalculateBMI(weight: 123, 64)); 

        // Named arguments can follow positional arguments.
        Console.WriteLine(CalculateBMI(123, height: 64));
    }

    static int CalculateBMI(int weight, int height)
    {
        return (weight * 703) / (height * height);
    }
}

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

В определении метода, конструктора, индексатора или делегата можно указать, что параметры являются обязательными или необязательными. При каждом вызове необходимо указывать аргументы для всех обязательных параметров, но можно опустить аргументы для необязательных параметров.

В рамках определения каждого необязательного параметра задается его значение по умолчанию. Если для параметра не передается аргумент, используется значение по умолчанию. Значение по умолчанию должно быть одним из следующих типов выражений:

Необязательные параметры определяются в конце списка параметров после всех обязательных параметров. Если вызывающий объект задает аргумент для какого-либо из последующих необязательных параметров, он должен задать аргументы для всех предшествующих необязательных параметров. Разделенные запятыми пустые позиции в списке аргументов не поддерживаются. Например, в следующем коде метод экземпляра ExampleMethod определен одним или двумя необязательными параметрами.

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

Следующий вызов ExampleMethod вызывает ошибку компилятора, поскольку аргумент предоставлен для третьего параметра, а не для второго.

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

Но если имя третьего параметра известно, задачу можно выполнить с использованием именованного аргумента.

anExample.ExampleMethod(3, optionalint: 4);

IntelliSense использует квадратные скобки для указания необязательных параметров, как показано на следующем рисунке.

Необязательные параметры в ExampleMethod

Быстрая справка IntelliSense для метода ExampleMethod.

Примечание

Кроме того, необязательные параметры можно определить с помощью класса .NET OptionalAttribute.Для параметров OptionalAttribute указывать значение по умолчанию не обязательно.

Пример

В следующем примере у конструктора класса ExampleClass имеется один параметр, который является необязательным. У метода экземпляра ExampleMethod имеется один обязательный параметр required и два необязательных параметра optionalstr и optionalint. В коде в методе Main показаны различные способы вызова конструктора и метода.

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.

}

Интерфейсы COM

Именованные и необязательные аргументы, а также поддержка динамических объектов и другие усовершенствования значительно улучшаю взаимодействие с интерфейсами API COM, например с API автоматизации Office.

Например, у метода AutoFormat в интерфейсе Microsoft Office Excel Range имеется семь параметров, все из которых необязательны. Эти параметры показаны на следующем рисунке.

Параметры AutoFormat

Быстрая справка IntelliSense для метода AutoFormat.

В C# 3.0 и предыдущих версиях для каждого параметра требуется аргумент, как показано в следующем примере.

// 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. Именованные и необязательные аргументы позволяют опустить аргумент необязательного параметра, если изменять значение параметра по умолчанию не требуется. В следующем вызове задается значение только для одного из семи параметров.

// 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 (Руководство по программированию на C#) и Практическое руководство. Доступ к объектам взаимодействия Office с помощью функций языка Visual C# (Руководство по программированию на C#).

Разрешение перегрузки

Использование именованных и необязательных аргументов следующим образом влияет на разрешение перегрузки:

  • метод, индексатор или конструктор является кандидатом на выполнение, если каждый из его параметров является необязательным или соответствует по имени или позиции одному аргументу в инструкции вызова, а этот аргумент можно преобразовать к типу параметра;

  • если обнаружено более одного кандидата, правила разрешения перегрузки для предпочтительных преобразований применяются к аргументам, которые заданы в явном виде. Опущенные аргументы для необязательных параметров игнорируются;

  • если два кандидата оказываются одинаково подходящими, предпочтение отдается кандидату, у которого нет необязательных параметров, аргументы которых были опущены в вызове. Это последовательность общего приоритета при разрешении перегрузки для кандидатов с меньшим числом параметров.

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

Дополнительные сведения см. в Спецификация языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

См. также

Задачи

Практическое руководство. Использование именованных и необязательных аргументов в программировании приложений Office (Руководство по программированию на C#)

Ссылки

Использование конструкторов (Руководство по программированию на C#)

Использование индексаторов (Руководство по программированию в C#)

Другие ресурсы

Использование типа dynamic (Руководство по программированию на C#)