当初は引数、パラメータの意味をごちゃごちゃにして使っていので、用語について簡単にメモします。
値渡しや参照渡しについても書いています。
パラメータ、仮引数
関数に定義されている、関数の中で使う変数名のこと。
関数定義側で表記されている、()の中に指定されている、変数名。
private int Sum(int intX) //←これがパラメータ
{
int intY = 0;
return intX + intY;
}
引数、実引数
関数呼び出し側で指定する値のこと。関数に渡す実際の値のこと。
パラメータで指定されているデータ型の値を渡す必要がある。
ちなみに英語ではargumentという。
private void DoSomeyhing()
{
Sum(1);//←これが引数
}
オプションパラメータ、省略可能引数(オプション引数)
関数、コンストラクタ、インデクサで、初期値が既に設定されているパラメータ。
呼び出すときに省略できて、その場合は初期値が適用される。
呼び出し元で、その引数の場に初期値とは違う値を入れたら、そちらが適用される。
関数を定義している側の目線で言うとオプションパラメータで、
呼び出し元の目線で言うと省略可能引数という言い方になる。
(※名前付きパラメータと書いてあるものもありますが、おそらく名前付き引数のことです。)
private int Sum(int intX, int intY = 0) //←intYがオプションパラメータ
{
return intX + intY;
}
private void DoSomeyhing()
{
Sum(1); //←オプションパラメータは省略できるので、省略可能引数とも呼ばれる
Sum(1, 1);//←省略せず、指定してあげることもできる
}
名前付き引数
オプションパラメータが複数ある関数、コンストラクタ、インデクサを呼び出す際に使用する。
呼び出し元の引数に名前を付けて、どのオプションパラメータかを指定できる。
//例えばオプションパラメータが同じint型で2つ以上あるとき(intYとintP)
private int Sum(int intX, int intY = 0, int intP = 0)
{
return intX + intY+ intP ;
}
private void DoSomeyhing()
{
//このように書くと、引数5は、先に指定してあるintYに代入され、intPは初期値0が使用される
Sum(1,5);
//intPに代入したい場合はこのように「パラメータ名:引数」と書いてあげる
Sum(1, intP:1);
//※可読性が上がるので、オプションパラメータが複数ある場合は、必要ない場合でも、名前付きで書いてあげると親切かもです
Sum(1, intY:5);
}
引数の値渡し
引数の渡し方の一種で、引数に指定した変数のコピーがメモリへ新たに作られる。
そのコピーされた変数を関数内でいじる。
よって、引数に指定した変数の中身には影響が出ない。
string strHello = "こんにちは";
//1.変数を値渡し。C#の場合、このまま変数を書くだけでOK
this.EchoHello(strHello);
//4."こんにちは"が出力される。呼び出し元には影響がでないのが特徴。
Console.WriteLine(strHello);
private void EchoHello(string strValue)
{
//2.パラメータ、【strValue】のコピーが作られて、コピー側の変数を使って、"Hello"を表示する処理を行う。
//(以下に追加を記載しています)
strValue = "Hello";
//3."Hello"が出力される
Console.WriteLine(strValue);
}
追記
以下の記事を参考に、かみ砕いた言葉で書いています。
メモリの使われ方などを表にされていて、大変分かりやすい記事です。
感謝いたします。
引数の参照渡し
引数の渡し方の一種で、引数に指定した変数の参照(変数の実態が存在している住所)をその関数に渡す。
つまり、関数内では、渡された参照値を元に変数の実態をいじることになるため、関数内で変数の値を書き換えると、呼び出し元の変数の中身も書き変わる。
string strHello = "こんにちは";
//1.関数を参照渡し(C#の場合、変数の前にをref書いてあげる)
this.EchoHello(ref strHello);
//4."Hello"が出力される。呼び出し元の変数にも反映されるので注意
Console.WriteLine(strHello);
private void EchoHello(ref string strValue)//パラメーターにもrefを書く必要がある
{
//2.パラメータ、【strValue】には【string strHello】の参照値が入っている
//(こちらもかみ砕いて書いています。)
strValue = "Hello";
//3.Helloが出力される
Console.WriteLine(strValue);
}
省略可能引数(オプション引数)とオーバロードの違い
コンパイル時の挙動が異なります。
省略可能引数を使用している関数は、コンパイルすると、呼び出し元の関数に省略可能引数の値が埋め込まれます。
よって、アセンブリの違うプロジェクト間で省略可能引数のある関数は基本的に使用せず、オーバーロードを使用します。(ライブラリなど)
例えば、省略可能引数の値を変更→コンパイルしても、
呼び出し元側には、古い方の省略可能引数の値が埋め込まれている状態になるので、
こちらもコンパイルし直さなければなりません。