具名和選擇性引數 (C# 程式設計手冊)Named and Optional Arguments (C# Programming Guide)

C# 4C# 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 介面,例如 Microsoft Office Automation API。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. 因為 sellerNameproductName 都是字串類型,所以可以使用具名引數來區分兩者,並減少讀取程式碼的任何人的混淆,而不是依位置傳送引數。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");

不過,如果失序具名引數的後面接著位置引數,則無效。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");

範例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 是實值型別,例如 enumstructan 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:

顯示 ExampleMethod 方法之 IntelliSense 快速諮詢的螢幕擷取畫面。

注意

您也可以使用 .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 和兩個選擇性參數 optionalstroptionalintInstance 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.

}

COM 介面COM Interfaces

具名和選擇性引數以及對動態物件和其他增強功能的支援,大幅改善與 COM API 的互通性,例如 Office Automation API。Named and optional arguments, along with support for dynamic objects and other enhancements, greatly improve interoperability with COM APIs, such as Office Automation APIs.

例如,Microsoft Office Excel Range 介面的 AutoFormat 方法有七個參數,都是選擇性參數。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:

顯示 AutoFormat 方法之 IntelliSense 快速諮詢的螢幕擷取畫面。

在 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);

不過,您可以使用 C# 4.0 引入的具名和選擇性引數,大幅簡化對 AutoFormat 的呼叫。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 程式設計中使用具名和選擇性引數如何:使用 Visual C# 功能存取 Office Interop 物件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