Argumenty nazwane i opcjonalne (Przewodnik programowania w języku C#)

Nazwane argumenty umożliwiają określenie argumentu dla parametru przez dopasowanie argumentu z jego nazwą, a nie z jego pozycją na liście parametrów. Opcjonalne argumenty umożliwiają pominięcie argumentów dla niektórych parametrów. Obie techniki mogą być używane z metodami, indeksatorami, konstruktorami i delegatami.

W przypadku używania argumentów nazwanych i opcjonalnych argumenty są oceniane w kolejności, w jakiej są wyświetlane na liście argumentów, a nie na liście parametrów.

Parametry nazwane i opcjonalne umożliwiają podawanie argumentów dla wybranych parametrów. Ta funkcja znacznie ułatwia wywołania interfejsów COM, takich jak interfejsy API usługi Microsoft Office Automation.

Argumenty nazwane

Nazwane argumenty umożliwiają dopasowywanie kolejności argumentów do kolejności parametrów na listach parametrów nazywanych metodami. Argument dla każdego parametru można określić za pomocą nazwy parametru. Na przykład funkcja, która drukuje szczegóły zamówienia (takie jak nazwa sprzedawcy, numer zamówienia i nazwa produktu) może być wywoływana przez wysyłanie argumentów według pozycji w kolejności zdefiniowanej przez funkcję.

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

Jeśli nie pamiętasz kolejności parametrów, ale znasz ich nazwy, możesz wysłać argumenty w dowolnej kolejności.

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

Argumenty nazwane zwiększają również czytelność kodu, identyfikując, co reprezentuje każdy argument. W poniższej sellerName przykładowej metodzie nie można mieć wartości null ani białych znaków. sellerName Zarówno jak i productName są typami ciągów, zamiast wysyłać argumenty według pozycji, warto użyć nazwanych argumentów, aby uściślić te dwa i zmniejszyć zamieszanie dla każdego, kto czyta kod.

Nazwane argumenty, jeśli są używane z argumentami pozycyjnymi, są prawidłowe tak długo, jak

  • nie są one zgodne z żadnymi argumentami pozycyjnymi lub

    PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
    
  • są one używane w prawidłowej pozycji. W poniższym przykładzie parametr orderNum znajduje się w prawidłowej pozycji, ale nie jest jawnie nazwany.

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

Argumenty pozycyjne, które są zgodne z dowolnymi argumentami nazwanych poza kolejnością, są nieprawidłowe.

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

Przykład

Poniższy kod implementuje przykłady z tej sekcji wraz z dodatkowymi.

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

Argumenty opcjonalne

Definicja metody, konstruktora, indeksatora lub delegata może określać jego parametry są wymagane lub opcjonalne. Każde wywołanie musi podać argumenty dla wszystkich wymaganych parametrów, ale może pominąć argumenty dla parametrów opcjonalnych.

Każdy opcjonalny parametr ma wartość domyślną w ramach jego definicji. Jeśli dla tego parametru nie zostanie wysłany żaden argument, zostanie użyta wartość domyślna. Wartość domyślna musi być jednym z następujących typów wyrażeń:

  • wyrażenie stałe;
  • wyrażenie formularza new ValType(), gdzie ValType jest typem wartości, takim jak wyliczenie lub struktura;
  • wyrażenie formularza default(ValType), gdzie ValType jest typem wartości.

Parametry opcjonalne są definiowane na końcu listy parametrów po wszelkich wymaganych parametrach. Jeśli obiekt wywołujący udostępnia argument dla dowolnego z kolejnych parametrów opcjonalnych, musi podać argumenty dla wszystkich poprzednich parametrów opcjonalnych. Luki rozdzielone przecinkami na liście argumentów nie są obsługiwane. Na przykład w poniższym kodzie metoda ExampleMethod wystąpienia jest definiowana z jednym wymaganym i dwoma parametrami opcjonalnymi.

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

Następujące wywołanie powoduje ExampleMethod błąd kompilatora, ponieważ argument jest dostarczany dla trzeciego parametru, ale nie dla drugiego.

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

Jeśli jednak znasz nazwę trzeciego parametru, możesz użyć nazwanego argumentu do wykonania zadania.

anExample.ExampleMethod(3, optionalint: 4);

Funkcja IntelliSense używa nawiasów do wskazywania opcjonalnych parametrów, jak pokazano na poniższej ilustracji:

Zrzut ekranu przedstawiający szybkie informacje o funkcji IntelliSense dla metody ExampleMethod.

Uwaga

Parametry opcjonalne można również zadeklarować przy użyciu klasy .NET OptionalAttribute . OptionalAttribute parametry nie wymagają wartości domyślnej. Jeśli jednak wymagana jest wartość domyślna, przyjrzyj DefaultParameterValueAttribute się klasie.

Przykład

W poniższym przykładzie konstruktor dla ExampleClass parametru ma jeden parametr, który jest opcjonalny. Metoda ExampleMethod wystąpienia ma jeden wymagany parametr, required, i dwa opcjonalne parametry optionalstr i optionalint. Kod w programie Main pokazuje różne sposoby wywoływanego konstruktora i metody.

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

Powyższy kod przedstawia kilka przykładów, w których opcjonalne parametry nie są prawidłowo stosowane. Pierwszy ilustruje, że argument musi zostać podany dla pierwszego parametru, który jest wymagany.

Atrybuty informacji o obiekcie wywołującym

Atrybuty informacji o obiektach wywołujących, takie jak CallerFilePathAttribute, CallerLineNumberAttribute, CallerMemberNameAttributei CallerArgumentExpressionAttribute, są używane do uzyskiwania informacji o obiekcie wywołującym metodę. Te atrybuty są szczególnie przydatne podczas debugowania lub rejestrowania informacji o wywołaniach metod.

Te atrybuty są opcjonalnymi parametrami z wartościami domyślnymi dostarczonymi przez kompilator. Obiekt wywołujący nie powinien jawnie podać wartości dla tych parametrów.

Interfejsy COM

Argumenty nazwane i opcjonalne wraz z obsługą obiektów dynamicznych znacznie zwiększają współdziałanie z interfejsami API com, takimi jak interfejsy API usługi Office Automation.

Na przykład AutoFormat metoda w interfejsie programu Microsoft Office Excel Range ma siedem parametrów, z których wszystkie są opcjonalne. Te parametry przedstawiono na poniższej ilustracji:

Zrzut ekranu przedstawiający szybkie informacje o funkcji IntelliSense dla metody Autoformatowania.

Jednak wywołanie metody można znacznie uprościć AutoFormat przy użyciu argumentów nazwanych i opcjonalnych. Argumenty nazwane i opcjonalne umożliwiają pominięcie argumentu dla opcjonalnego parametru, jeśli nie chcesz zmieniać wartości domyślnej parametru. W poniższym wywołaniu jest określona wartość tylko dla jednego z siedmiu parametrów.

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

Aby uzyskać więcej informacji i przykładów, zobacz How to use named and optional arguments in Office programming and How to access Office interop objects by using C# features (Jak używać argumentów nazwanych i opcjonalnych w programowaniu pakietu Office) oraz How to access Office interop objects by using C# features (Jak uzyskać dostęp do obiektów międzyoperacyjności pakietu Office przy użyciu funkcji języka C#).

Rozpoznanie przeciążenia

Użycie nazwanych i opcjonalnych argumentów wpływa na rozpoznawanie przeciążeń w następujący sposób:

  • Metoda, indeksator lub konstruktor jest kandydatem do wykonania, jeśli każdy z jego parametrów jest opcjonalny lub odpowiada, według nazwy lub pozycji, do pojedynczego argumentu w instrukcji wywołującej i ten argument można przekonwertować na typ parametru.
  • Jeśli zostanie znalezionych więcej niż jeden kandydat, reguły rozpoznawania przeciążenia dla preferowanych konwersji są stosowane do argumentów, które są jawnie określone. Pominięte argumenty parametrów opcjonalnych są ignorowane.
  • Jeśli dwaj kandydaci są oceniani jako równie dobrzy, preferencja trafia do kandydata, który nie ma opcjonalnych parametrów, dla których argumenty zostały pominięte w wywołaniu. Rozpoznawanie przeciążenia zazwyczaj preferuje kandydatów, którzy mają mniej parametrów.

specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.