メソッド呼び出し時に引数を省略できるようにするには、その引数をオプション引数とするか、メソッドをオーバーロードする。それらの方法と注意点を解説する。
オプション引数(省略可能な引数)とは、メソッドを呼び出すときにその引数の一部を省略できる機能である。本稿では、オプション引数が使えるメソッドの作り方と、その使い方を解説する。
メソッドの引数に既定値を与えればよい。Visual Basic(以降、VB)では、引数の前にOptionalキーワードも必要だ(次のコード)。
ただし、オプション引数の途中や後ろに通常の引数は置けない。通常の引数を並べてから、その後ろにオプション引数を並べる。
// 呼び出すときに引数x/y/zのいずれも省略可能(オプション引数)
public static int SampleMethod1(int x = 0, int y = 0, int z = 0)
=> x + y * 2 + z * 3;
// オプション引数(y/z)は通常の引数(x)の後ろにしか置けない
public static int SampleMethod1a(int x, int y = 0, int z = 0)
=> x + y * 2 + z * 3;
// オプション引数の途中や後ろに通常の引数を置くとコンパイルエラー
//public static int SampleMethod1b(int x = 0, int y, int z = 0)
// => x + y * 2 + z * 3;
' 呼び出すときに引数x/y/zのいずれも省略可能(オプション引数)
Public Function SampleMethod1(Optional x As Integer = 0,
Optional y As Integer = 0,
Optional z As Integer = 0) As Integer
Return x + y * 2 + z * 3
End Function
' オプション引数(y/z)は通常の引数(x)の後ろにしか置けない
Public Function SampleMethod1a(x As Integer,
Optional y As Integer = 0,
Optional z As Integer = 0) As Integer
Return x + y * 2 + z * 3
End Function
' オプション引数の途中や後ろに通常の引数を置くとコンパイルエラー
'Public Function SampleMethod1b(Optional x As Integer = 0,
' y As Integer,
' Optional z As Integer = 0) As Integer
' Return x + y * 2 + z * 3
'End Function
メソッドを呼び出すとき、引数の位置や引数の名前を使って必要な引数だけを与える(次のコード)。省略した引数は、メソッド側に定義してある既定値になる。
引数の位置によって省略するとき、C#では途中の引数を省略できない。VBでは途中の引数も省略できる。
// 全ての引数を与える例
WriteLine($"SampleMethod1(1,2,3)={SampleMethod1(1, 2, 3)}");
// 出力:SampleMethod1(1,2,3)=14
// 1a. 引数順序で省略(第3引数を省略する例)
WriteLine($"SampleMethod1(1,2)={SampleMethod1(1,2)}");
// 出力:SampleMethod1(1,2)=5
// 1b. 第2引数を省略する例(C#ではコンパイルエラー)
//WriteLine($"SampleMethod1(1,,3)={SampleMethod1(1,,3)}");
// 2. 名前付き引数を使って省略(第1引数xを省略する例)
WriteLine($"SampleMethod1(y:1,z:2)={SampleMethod1(y:1,z:2)}");
// 出力:SampleMethod1(y:1,z:2)=8
' 全ての引数を与える例
WriteLine($"SampleMethod1(1,2,3)={SampleMethod1(1, 2, 3)}")
' 出力:SampleMethod1(1,2,3)=14
' 1a. 引数順序で省略(第3引数を省略する例)
WriteLine($"SampleMethod1(1,2)={SampleMethod1(1, 2)}")
' 出力:SampleMethod1(1,2)=5
' 1b. 第2引数を省略する例(VBでは可能)
WriteLine($"SampleMethod1(1,,3)={SampleMethod1(1, , 3)}")
' 出力:SampleMethod1(1,,3)=10
' 2. 名前付き引数を使って省略(第1引数xを省略する例)
WriteLine($"SampleMethod1(y:=1,z:=2)={SampleMethod1(y:=1, z:=2)}")
' 出力:SampleMethod1(y:=1,z:=2)=8
オプション引数と同様なことは、メソッドのオーバーロードでも可能だ。C# 4.0以前では、オプション引数がなかったので、先の「SampleMethod1」メソッドは次のコードのようにしていた(C#のみ示す)。
オーバーロードとの相違点は、オプション引数の方がコードの記述が少なくて済むことや、名前付き引数を使えば途中の引数も省略できることなどが挙げられる。
相違点で特に気を付けなければならないのは、既定値がコンパイル後にどこに配置されるかである。オプション引数の場合は、コンパイル時に既定値が解決され、呼び出し側に埋め込まれる。オーバーロードの場合は、メソッド内部だ。オプション引数の場合は、既定値を変更しても、呼び出し側をコンパイルするまで反映されない。十分に注意してほしい(クラスライブラリを作るときにはオプション引数は避けた方が無難である)。
public static int SampleMethod1()
=> SampleMethod1(0);
public static int SampleMethod1(int x)
=> SampleMethod1(x, 0);
public static int SampleMethod1(int x, int y)
=> SampleMethod1(x, y, 0);
public static int SampleMethod1(int x, int y, int z)
=> x + y * 2 + z * 3;
オーバーロードや参照渡しとは併用しないようにしよう。
VBでは、オプション引数と参照渡しを併用できる(C#ではコンパイルできない)。すると、オプション引数を出力用(メソッドから結果を受け取る)としても使えてしまう。オプション引数=省略可能であるのに、結果を受け取るにはオプション引数が必要というのでは、使う側は混乱してしまうだろう。
オーバーロードとオプション引数は、C#でもVBでも併用できる(次のコード)。両方に当てはまる呼び出し方をした場合、実際にはどちらが呼び出されるのだろうか? 原則はオプション引数のない方である。ただし、名前付き引数を使えば、優先順序を引っ繰り返せる。コードを読むときにそのよう難しいルールを思い出さねばならないというのは、あまりうれしくないだろう。
// オプション引数を持つメソッド
public static int SampleMethod1(int x = 0, int y = 0, int z = 0)
=> x + y * 2 + z * 3;
// メソッドのオーバーロード
public static int SampleMethod1(int n)
=> -n;
……省略……
// オーバーロードとオプション引数の優先順位
WriteLine($"SampleMethod1(1)={SampleMethod1(1)}");
// 出力:SampleMethod1(1)=-1 ⇒ オーバーロードの方が呼び出された
WriteLine($"SampleMethod1(x:1)={SampleMethod1(x:1)}");
// 出力:SampleMethod1(x:1)=1 ⇒ オプション引数の方が呼び出された
' オプション引数を持つメソッド
Public Function SampleMethod1(Optional x As Integer = 0,
Optional y As Integer = 0,
Optional z As Integer = 0) As Integer
Return x + y * 2 + z * 3
End Function
' メソッドのオーバーロード
Public Function SampleMethod1(n As Integer) As Integer
Return -n
End Function
……省略……
' オーバーロードとオプション引数の優先順位
WriteLine($"SampleMethod1(1)={SampleMethod1(1)}")
' 出力:SampleMethod1(1)=-1 ⇒ オーバーロードの方が呼び出された
WriteLine($"SampleMethod1(x:=1)={SampleMethod1(x:=1)}")
' 出力:SampleMethod1(x:=1)=1 ⇒ オプション引数の方が呼び出された
オプション引数が使えるメソッドを作るには、メソッドの引数に既定値を与える。VBでは、引数の前にOptionalキーワードも付ける。オーバーロードや参照渡しとの併用は、混乱を招くので行わないようにしよう。
利用可能バージョン:Visual Basic .NET以降/Visual Studio 2010(C# 4.0)以降
カテゴリ:C# 処理対象:言語構文
カテゴリ:Visual Basic .NET 処理対象:言語構文
関連TIPS:数値を右詰めや0埋めで文字列化するには?[C#、VB]
Copyright© Digital Advantage Corp. All Rights Reserved.