この章のテーマ §
メソッドの引数に付加するin、out、ref、paramsキーワードについて学びます。引数で行う変数宣言についても学びます。
前提知識 §
Console.WriteLineメソッド, 文字列の基礎, 変数の基礎, メソッドの基礎, 配列の基礎, int型, foreach文
解説 §
メソッドの引数には、in、out、ref、paramsキーワードを付けることができます。
具体的に使用した例はサンプルソースのsubメソッドの引数を見て下さい。
それぞれの意味は以下の通りです。
- 何も指定しない 引数を書き換えることはできるが、元のメソッドには反映されない
- in メソッドに渡すだけ。書き換えることはできない。
- out メソッドから値を返すだけ。値を渡すためには使えない。
- ref 値を受け取って書き換えると呼び出し元にも反映される
- params 任意個数の引数を列挙できる機能を実現する
paramsだけは使い方が特殊で、引数にparamsキーワード付きの配列の引数を書いておくと、呼び出し側は任意個数の引数を記述できます。サンプルソースの利用例の通りです。
罠の数々 §
- 値を呼び出し側が受け取る引数の場合、呼び出し側は引数として変数を書かねばならない。任意の式や定数を書いても値を受け取れないからである
- paramsを付加できるのは最後の引数だけである
- paramsを付加した引数には値を列挙する代わりに配列を渡すこともできる
- out/refは、使用ができない場合や機能に制約を受ける場合もあるので、戻り値で値を受け取る方が良い。受け取りたい値が2つ以上あるときは、Tupleなどの複数の値を1つにまとめる機能の利用を検討しよう
参考リンク §
パラメーターの引き渡し (C# プログラミング ガイド)
params (C# リファレンス)
サンプルソース: passingParameters §
int a0 = 1;
int b0 = 2;
int d0 = 4;
int e0 = 5;
int e1 = 6;
int e2 = 7;
Console.WriteLine($"a0={a0}");
Console.WriteLine($"b0={b0}");
Console.WriteLine($"d0={d0}");
Console.WriteLine($"e0={e0}");
Console.WriteLine($"e1={e1}");
Console.WriteLine($"e2={e2}");
sub(a0, in b0, out int c0, ref d0, e0, e1, e2);
Console.WriteLine($"a0={a0}");
Console.WriteLine($"b0={b0}");
Console.WriteLine($"c0={c0}");
Console.WriteLine($"d0={d0}");
void sub(int a, in int b, out int c, ref int d, params int[] e)
{
Console.WriteLine("sub called");
a = a + 1;
Console.WriteLine($"b={b}");
// 以下の行は許されない。bには書き込めない
//b = b + 1;
// 以下の行は許されない。cは読み出せない
//c = c + 1;
c = 999;
d = d + 1;
foreach (var item in e) Console.WriteLine($"item={item}");
Console.WriteLine("sub done");
}
実行結果 §
a0=1
b0=2
d0=4
e0=5
e1=6
e2=7
sub called
b=2
item=5
item=6
item=7
sub done
a0=1
b0=2
c0=999
d0=5
リポジトリ §
https://github.com/autumn009/CSharpPrimer2
練習問題 §
以下のプログラムは実行すると123を出力する。正しsubメソッドの引数の書式(***の部分)はどれだろうか。
sub(***);
Console.WriteLine(x);
void sub(out int x) => x = 123;
- int x
- out x
- out int x
- out 123
- out int 123
[[解答]]