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()
, kdeValType
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:
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, required
a 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:
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#.