Pojmenované a nepovinné argumenty (Průvodce programováním v C#)

Pojmenované argumenty umožňují zadat argument pro parametr tak, že se argument shoduje s jeho názvem, nikoli s jeho umístěním v seznamu parametrů. Volitelné argumenty umožňují vynechat argumenty pro některé parametry. Obě techniky lze použít s metodami, indexery, konstruktory a delegáty.

Při použití pojmenovaných a nepovinných argumentů se argumenty vyhodnocují v pořadí, ve kterém se zobrazují v seznamu argumentů, nikoli v seznamu parametrů.

Pojmenované a volitelné parametry umožňují zadat argumenty pro vybrané parametry. Tato funkce výrazně usnadňuje volání rozhraní MODELU COM, jako jsou rozhraní API služby systém Microsoft Office Automation.

Pojmenované argumenty

Pojmenované argumenty vám umožňují shodovat pořadí argumentů s pořadím parametrů v seznamech parametrů volaných metod. Argument pro každý parametr lze zadat podle názvu parametru. Funkci, která například vytiskne podrobnosti objednávky (například název prodejce, číslo objednávky a název produktu), může být volána odesláním argumentů podle pozice v pořadí definovaném funkcí.

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

Pokud si nepamatujete pořadí parametrů, ale znáte jejich názvy, můžete argumenty odeslat v libovolném pořadí.

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

Pojmenované argumenty také zlepšují čitelnost kódu tím, že identifikují, co jednotlivé argumenty představují. V níže uvedené sellerName ukázkové metodě nesmí být null ani prázdné znaky. Protože se jedná sellerName o productName typy řetězců, místo odesílání argumentů podle pozice dává smysl použít pojmenované argumenty k nejednoznačnosti těchto dvou a omezit nejasnosti pro každého, kdo kód čte.

Pojmenované argumenty, pokud se používají s pozičními argumenty, jsou platné, pokud jsou

  • nejsou následované žádnými pozičními argumenty nebo

    PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
    
  • používají se ve správné pozici. V následujícím příkladu je parametr orderNum ve správné pozici, ale není explicitně pojmenovaný.

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

Poziční argumenty, které následují za libovolnými pojmenovanými argumenty mimo pořadí, jsou neplatné.

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

Příklad

Následující kód implementuje příklady z této části spolu s některými dalšími.

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

Volitelné argumenty

Definice metody, konstruktoru, indexeru nebo delegáta může určovat parametry, které jsou povinné nebo volitelné. Jakékoli volání musí poskytovat argumenty pro všechny požadované parametry, ale může vynechat argumenty pro volitelné parametry.

Každý volitelný parametr má jako součást definice výchozí hodnotu. Pokud pro tento parametr není odeslán žádný argument, použije se výchozí hodnota. Výchozí hodnota musí být jedním z následujících typů výrazů:

  • konstantní výraz;
  • výraz formuláře new ValType(), kde ValType je typ hodnoty, například výčtu nebo struktury;
  • výraz default(ValType) formuláře, kde ValType je typ hodnoty.

Volitelné parametry jsou definovány na konci seznamu parametrů za všemi požadovanými parametry. Pokud volající poskytne argument pro některý z po sobě jdoucích volitelných parametrů, musí poskytnout argumenty pro všechny předchozí volitelné parametry. Mezery oddělené čárkami v seznamu argumentů se nepodporují. Například v následujícím kódu je metoda ExampleMethod instance definována s jedním povinným a dvěma volitelnými parametry.

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

Následující volání ExampleMethod způsobí chybu kompilátoru, protože argument je zadaný pro třetí parametr, ale ne pro druhý.

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

Pokud ale znáte název třetího parametru, můžete k provedení úkolu použít pojmenovaný argument.

anExample.ExampleMethod(3, optionalint: 4);

IntelliSense používá hranaté závorky k označení volitelných parametrů, jak je znázorněno na následujícím obrázku:

Snímek obrazovky s rychlými informacemi Technologie IntelliSense pro metodu ExampleMethod

Poznámka:

Volitelné parametry můžete deklarovat také pomocí třídy .NET OptionalAttribute . OptionalAttribute parametry nevyžadují výchozí hodnotu. Pokud je však požadovaná výchozí hodnota, podívejte se na DefaultParameterValueAttribute třídu.

Příklad

V následujícím příkladu má konstruktor ExampleClass pro jeden parametr, který je volitelný. Metoda ExampleMethod instance má jeden povinný parametr, requireda dva volitelné parametry optionalstr a optionalint. Kód ukazuje Main různé způsoby, jak lze vyvolat konstruktor a metodu.

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

Předchozí kód ukazuje řadu příkladů, kde se nepoužijí volitelné parametry správně. První ukazuje, že argument musí být zadán pro první parametr, který je povinný.

Atributy informací o volajícím

Atributy informací volajícího, například CallerFilePathAttribute, CallerLineNumberAttribute, CallerMemberNameAttributea CallerArgumentExpressionAttribute, slouží k získání informací o volající metodě. Tyto atributy jsou zvlášť užitečné, když ladíte nebo potřebujete protokolovat informace o voláních metod.

Tyto atributy jsou volitelné parametry s výchozími hodnotami zadanými kompilátorem. Volající by neměl explicitně zadávat hodnotu pro tyto parametry.

Rozhraní MODELU COM

Pojmenované a volitelné argumenty spolu s podporou dynamických objektů výrazně zlepšují interoperabilitu s rozhraními COM API, jako jsou rozhraní API služby Office Automation.

Například AutoFormat metoda v rozhraní systém Microsoft Office Excelu Range má sedm parametrů, z nichž všechny jsou volitelné. Tyto parametry jsou znázorněny na následujícím obrázku:

Snímek obrazovky s rychlými informacemi Technologie IntelliSense pro metodu Automatický formát

Volání ale můžete výrazně zjednodušit AutoFormat pomocí pojmenovaných a volitelných argumentů. Pojmenované a volitelné argumenty umožňují vynechat argument pro volitelný parametr, pokud nechcete změnit výchozí hodnotu parametru. V následujícím volání je hodnota určena pouze pro jeden ze sedmi parametrů.

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

Další informace a příklady naleznete v tématu Jak používat pojmenované a volitelné argumenty v programovánía Jak získat přístup k objektům interoperability Office pomocí funkcí jazyka C#.

Rozlišení přetěžování

Použití pojmenovaných a volitelných argumentů ovlivňuje rozlišení přetížení následujícími způsoby:

  • Metoda, indexer nebo konstruktor je kandidátem pro spuštění, pokud každý z jeho parametrů je volitelný nebo odpovídá, podle názvu nebo pozice, k jednomu argumentu ve volajícím příkazu a tento argument lze převést na typ parametru.
  • Pokud se najde více než jeden kandidát, použijí se pravidla překladu přetížení pro upřednostňované převody na argumenty, které jsou explicitně zadány. Vynechané argumenty pro volitelné parametry se ignorují.
  • Pokud jsou dva kandidáti vyhodnoceni jako stejně dobrý, preference přejde k kandidátovi, který nemá volitelné parametry, pro které byly argumenty vynechány ve volání. Rozlišení přetížení obecně preferuje kandidáty, kteří mají méně parametrů.

specifikace jazyka C#

Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.