名前付き引数と省略可能な引数 (C# プログラミング ガイド)
"名前付き引数" を使用すると、引数をそのパラメーター リスト内の位置ではなく名前で照合することで、パラメーターの引数を指定できます。 省略可能な引数を使用すると、一部のパラメーターの引数を省略できます。 両方の手法をメソッド、インデクサー、コンストラクター、デリゲートで使用できます。
名前付き引数と省略可能な引数を使用すると、引数は、パラメーター リストではなく、引数リストに記述されている順に評価されます。
名前付きパラメーターと省略可能なパラメーターを使用すると、選択したパラメーターの引数を指定できます。 この機能により、Microsoft Office オートメーション API などの COM インターフェイスの呼び出しが大幅に簡素化されます。
名前付き引数
名前付き引数を使用すると、引数の順序を、呼び出されたメソッドのパラメーター リスト内のパラメーターの順序に一致させる必要がなくなります。 各パラメーターの引数はパラメーター名で指定できます。 たとえば、注文の詳細 (販売者の名前、注文番号、製品名など) を出力する関数は、引数を位置によって、その関数で定義されている順序に従って渡すことで呼び出せます。
PrintOrderDetails("Gift Shop", 31, "Red Mug");
パラメーターの順序を覚えていなくても、それらの名前がわかっていれば、任意の順序で引数を渡すことができます。
PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");
PrintOrderDetails(productName: "Red Mug", sellerName: "Gift Shop", orderNum: 31);
また、名前付き引数を使用すると、各引数が表すものが識別しやすくなり、コードが読みやすくなります。 次のメソッド例では、sellerName
は null にしたり、空白にしたりできません。 sellerName
と productName
はいずれも文字列型であり、引数を位置によって渡すより、名前付き引数を使用するほうが合理的です。2 つのあいまいさが取り除かれ、コードを読む人の混乱が少なくなります。
名前付き引数は、位置引数と共に使用するとき、次の場合において有効となります
後ろに位置引数が続かない。
PrintOrderDetails("Gift Shop", 31, productName: "Red Mug");
正しい位置で使用されます。 下の例では、パラメーター
orderNum
は正しい位置にありますが、明示的に名前が付けられていません。PrintOrderDetails(sellerName: "Gift Shop", 31, productName: "Red Mug");
後に位置引数が続く場合、順序が正しくない名前付き引数は無効になります。
// This generates CS1738: Named argument specifications must appear after all fixed arguments have been specified.
PrintOrderDetails(productName: "Red Mug", 31, "Gift Shop");
例
次のコードでは、このセクションの例の実装し、さらにいくつかのプログラミングを追加しています。
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}");
}
}
省略可能な引数。
メソッド、コンストラクター、インデクサー、デリゲートの定義では、そのパラメーターが必須であるか、省略可能であるかを指定できます。 どの呼び出しでも、すべての必須パラメーターに対して引数を指定する必要があります。ただし、省略可能なパラメーターの引数は省略できます。
省略可能な各パラメーターには、パラメーターの定義に既定値が含まれています。 そのパラメーターの引数を渡さない場合、既定値が使用されます。 既定値には、次のいずれかの種類の式を指定できます。
- 定数式
new ValType()
形式の式です。ValType
は、enum や struct のような値型になります。- default(ValType) 形式の式です。
ValType
は値の型です。
省略可能なパラメーターは、パラメーター リストの末尾で必須パラメーターの後に定義されます。 呼び出し元は、連続する省略可能なパラメーターのいずれか 1 つに対して引数を指定する場合、先行するすべての省略可能なパラメーターに引数を指定する必要があります。 引数リストでコンマで区切られたスペースを使用することはできません。 たとえば、次のコードでは、1 つの必須パラメーターと 2 つの省略可能パラメーターでインスタンス メソッド ExampleMethod
が定義されます。
public void ExampleMethod(int required, string optionalstr = "default string",
int optionalint = 10)
次に示す ExampleMethod
の呼び出しでは、3 つ目のパラメーターに引数が指定されていますが、2 つ目のパラメーターには指定されていないため、コンパイル エラーが発生します。
//anExample.ExampleMethod(3, ,4);
ただし、3 つ目のパラメーターの名前がわかっている場合、名前付き引数を使用してタスクを実行できます。
anExample.ExampleMethod(3, optionalint: 4);
次の例に示すように、IntelliSense では、省略可能なパラメーターを角かっこで示します。
注意
また、.NET OptionalAttribute クラスを使用して省略可能なパラメーターを宣言することもできます。 OptionalAttribute
パラメーターに既定値は必要ありません。 ただし、既定値が必要な場合は、DefaultParameterValueAttribute クラスをご確認ください。
例
次の例では、ExampleClass
のコンストラクターに省略可能なパラメーターが 1 つあります。 ExampleMethod
インスタンス メソッドには、required
という 1 つの必須パラメーターと、optionalstr
と optionalint
という 2 つの省略可能なパラメーターがあります。 Main
のコードに示すように、いくつかの異なる方法でコンストラクターとメソッドを呼び出すことができます。
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.
}
上記のコードでは、省略可能なパラメーターが正しく適用されていない例がいくつか示されています。 最初の例は、必須である 1 番目のパラメーターに引数を指定する必要があることを示しています。
呼び出し元情報属性
CallerFilePathAttribute、CallerLineNumberAttribute、CallerMemberNameAttribute、CallerArgumentExpressionAttribute などの呼び出し元情報属性は、メソッドの呼び出し元に関する情報を取得するために使用されます。 これらの属性は、デバッグ中やメソッド呼び出しに関する情報をログに記録する必要がある場合に特に便利です。
これらの属性は、コンパイラによって提供される既定値を持つ省略可能なパラメーターです。 呼び出し元は、これらのパラメーターの値を明示的に指定しないでください。
COM インターフェイス
名前付き引数と省略可能な引数を動的オブジェクトのサポートと併用すると、Office オートメーション API などの COM API との相互運用性が大幅に向上します。
たとえば、Microsoft Office Excel Range インターフェイスの AutoFormat メソッドには 7 つのパラメーターがあります。それらはすべて省略可能です。 これらのパラメーターを次の例に示します。
しかし、名前付き引数と省略可能な引数を使用すると、AutoFormat
の呼び出しを大幅に簡略化できます。 名前付き引数と省略可能な引数を使用すると、パラメーターの既定値を変更する必要がない場合に、省略可能なパラメーターの引数を省略できます。 次の呼び出しでは、7 つのパラメーターのうちの 1 つのパラメーターのみに値を指定しています。
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 );
詳細と例については、「Office プログラミングで名前付き引数と省略可能な引数を使用する方法」と「C# の機能を使用して Office 相互運用オブジェクトにアクセスする方法」を参照してください。
オーバーロードの解決
名前付き引数と省略可能な引数を使用すると、オーバーロードの解決に次のように影響します。
- メソッド、インデクサー、コンストラクターのパラメーターのそれぞれが任意であるか、名前か位置により、呼び出しステートメントの 1 つの引数に対応するとき、その引数がパラメーターの型に変換できる場合、メソッド、インデクサー、コンストラクターが実行の候補になります。
- 複数の候補が見つかった場合、明示的に指定される引数には、優先変換に関するオーバーロード解決の規則が適用されます。 任意のパラメーターの省略された引数は無視されます。
- 2 つの候補が等しく良好であると判断された場合、呼び出しで引数が省略された省略可能なパラメーターのない候補が優先されます。 オーバーロードの解決では、一般的にパラメーターの少ない候補が優先されます。
C# 言語仕様
詳細については、「C# 言語の仕様」を参照してください。 言語仕様は、C# の構文と使用法に関する信頼性のある情報源です。
.NET