Benannte und optionale Argumente (C#-Programmierhandbuch)

Mithilfe von benannten Argumenten können Sie ein Argument für einen Parameter angeben, indem Sie das Argument mit dem Namen des Parameters anstatt mit seiner Position in der Parameterliste abgleichen. Optionale Argumente ermöglichen es Ihnen, Argumente für einige Parameter auszulassen. Beide Techniken können mit Methoden, Indexern, Konstruktoren und Delegaten verwendet werden.

Wenn Sie benannte und optionale Argumente verwenden, werden die Argumente in der Reihenfolge ausgewertet, in der sie in der Argumentliste, nicht in der Parameterliste, erscheinen.

Mit benannten und optionalen Parametern können Sie Argumente für ausgewählte Parameter bereitstellen. Diese Funktion erleichtert den Zugriff auf COM-Schnittstellen wie etwa die Automation-APIs in Microsoft Office erheblich.

Benannte Argumente

Durch benannte Argumente müssen Sie die Reihenfolge der Argumente nicht mehr an die Reihenfolge der Parameter in den Parameterlisten der aufgerufenen Methoden anpassen. Das Argument für jeden Parameter kann durch den Parameternamen angegeben werden. Eine Funktion, die beispielsweise Details zu einer Bestellung ausgibt (z. B. Verkäufername, Bestellnummer und Produktname), kann aufgerufen werden, indem anhand der Position Argumente in der Reihenfolge gesendet werden, die von der Funktion definiert wurde.

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

Wenn Sie sich nicht an die Reihenfolge der Parameter erinnern, aber deren Namen kennen, können Sie die Argumente in einer beliebigen Reihenfolge senden.

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

Benannte Argumente verbessern auch die Lesbarkeit des Codes, indem sie identifizieren, was jedes Argument darstellt. In der folgenden Beispielmethode darf sellerName nicht NULL sein oder Leerzeichen enthalten. Da es sich bei sellerName und productName um Zeichenfolgentypen handelt, sollten Sie benannte Argumente verwenden, anstatt Argumente nach Position zu senden, um die beiden Parameter zu unterscheiden und die Leser des Codes nicht zu verwirren.

Benannte Argumente sind länger gültig, wenn sie mit positionellen Argumenten verwendet werden, da

  • ihnen keine positionellen Argumente folgen, bzw. da

    PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
    
  • sie in der richtigen Position verwendet werden. Im folgenden Beispiel befindet sich der Parameter orderNum in der richtigen Position, ist jedoch nicht explizit benannt.

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

Positionelle Argumente, die auf fehlerhafte benannte Argumente folgen, sind ungültig.

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

Beispiel

Der folgende Code implementiert die Beispiele in diesem Abschnitt sowie einige zusätzliche Beispiele.

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

Optionale Argumente

Die Definition einer Methode, eines Konstruktors, eines Indexers oder eines Delegaten kann angeben, dass deren Parameter benötigt werden oder optional sind. Jeder Aufruf muss Argumente für alle benötigten Parameter bereitstellen, kann aber Argumente für optionale Parameter auslassen.

Jeder optionale Parameter hat einen Standardwert als Teil seiner Definition. Wenn für diesen Parameter kein Argument gesendet wird, wird der Standardwert verwendet. Ein Standardwert muss einer der folgenden Typen von Ausdrücken sein:

  • Ein konstanter Ausdruck
  • Ein Ausdruck der Form new ValType(), wobei ValType ein Werttyp wie enum oder struct ist
  • ein Ausdruck in Form von default(ValType), wobei ValType ein Werttyp ist.

Optionale Parameter werden am Ende der Parameterliste nach den erforderlichen Parametern definiert. Wenn der Aufrufer ein Argument für einen beliebigen Parameter aus einer Folge von optionalen Parametern bereitstellt, muss er Argumente für alle vorherigen optionalen Parameter bereitstellen. Durch Trennzeichen getrennte Lücken in der Argumentliste werden nicht unterstützt. Im folgenden Code wird z.B. die Instanzmethode ExampleMethod mit einem erforderlichen und zwei optionalen Parametern definiert.

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

Der folgende Aufruf von ExampleMethod verursacht einen Compilerfehler, da ein Argument für den dritten Parameter, aber nicht für den zweiten, bereitgestellt wird.

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

Wenn Sie den Namen des dritten Parameters kennen, können Sie ein benanntes Argument zum Ausführen der Aufgabe verwenden.

anExample.ExampleMethod(3, optionalint: 4);

IntelliSense verwendet wie in der folgenden Abbildung gezeigt zum Anzeigen von optionalen Parametern Klammern:

Screenshot der IntelliSense-QuickInfo für die Methode „ExampleMethod“

Hinweis

Sie können auch optionale Parameter mit der .NET-Klasse OptionalAttribute deklarieren. OptionalAttribute-Parameter erfordern keinen Standardwert. Wenn jedoch ein Standardwert gewünscht wird, sehen Sie sich die DefaultParameterValueAttribute-Klasse an.

Beispiel

Im folgenden Beispiel hat der Konstruktor für ExampleClass einen Parameter, der optional ist. Instanzmethode ExampleMethod hat einen erforderlichen Parameter (required) und zwei optionale Parameter (optionalstr und optionalint). Der Code in Main veranschaulicht die unterschiedlichen Methoden, in denen der Konstruktor und die Methode aufgerufen werden können.

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

Der obige Code zeigt eine Reihe von Beispielen, in denen optionale Parameter nicht ordnungsgemäß angewendet werden. Das erste Beispiel veranschaulicht, dass für den ersten Parameter, der erforderlich ist, ein Argument angegeben werden muss.

Aufruferinformationsattribute

Aufruferinformationsattribute wie CallerFilePathAttribute, CallerLineNumberAttribute, CallerMemberNameAttribute und CallerArgumentExpressionAttribute werden verwendet, um Informationen zum Aufrufer einer Methode abzurufen. Diese Attribute sind besonders nützlich, wenn Sie debuggen oder Informationen zu Methodenaufrufen protokollieren müssen.

Diese Attribute sind optionale Parameter mit Standardwerten, die vom Compiler bereitgestellt werden. Der Aufrufer sollte nicht explizit einen Wert für diese Parameter angeben.

COM-Schnittstellen

Benannte und optionale Argumente verbessern zusammen mit der Unterstützung von dynamischen Objekten deutlich die Interoperabilität mit COM-APIs wie Office Automation-APIs.

Beispielsweise verfügt die Methode AutoFormat in der Range-Schnittstelle von Microsoft Office Excel über sieben Parameter, von denen alle optional sind. Diese Parameter sind in der folgenden Abbildung dargestellt:

Screenshot der IntelliSense-QuickInfo für die Methode „AutoFormat“

Sie können jedoch den Aufruf an AutoFormat erheblich vereinfachen, indem Sie benannte und optionale Argumente verwenden. Benannte und optionale Parameter helfen Ihnen dabei, das Argument für einen optionalen Parameter auszulassen, wenn Sie den Standardwert des Parameters nicht ändern möchten. Im folgenden Aufruf wird ein Wert für nur einen der sieben Parameter angegeben.

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

Weitere Informationen und Beispiele finden Sie unter Vorgehensweise: Verwenden von benannten und optionalen Argumenten in der Office-Programmierung und Vorgehensweise: Zugreifen auf Office Interop-Objekte mithilfe von C#-Funktionen.

Überladungsauflösung

Das Verwenden von benannten und optionalen Argumenten wirkt sich auf die Überladungsauflösung folgendermaßen aus:

  • Eine Methode, ein Indexer oder ein Konstruktor ist ein Kandidat für die Ausführung, wenn jeder der Parameter entweder optional ist oder über Namen oder Position auf ein einzelnes Argument in der aufrufenden Anweisung reagiert. Dieses Argument kann in dem Typ des Parameters konvertiert werden.
  • Wenn mehr als ein Kandidat gefunden wird, werden die Regeln der Überladungsauflösung als bevorzugte Konvertierungen auf die Argumente angewandt, die ausdrücklich angegeben sind. Ausgelassene Argumente für optionale Parameter werden ignoriert.
  • Wenn zwei Kandidaten gleich gut geeignet sind, wird ein Kandidat bevorzugt, der keine optionalen Parameter besitzt, für die Argumente im Aufruf ausgelassen wurden. Bei der Überladungsauflösung werden normalerweise Kandidaten mit weniger Parametern bevorzugt.

C#-Sprachspezifikation

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.