未分類

C# 値渡しと参照渡しの違い

準備

(なし)

デザイン

1. フォーム (Form1) にボタン (button1) を配置します。
2. フォーム (Form1) にリストボックス (listBox1) を配置します。

サンプルコード (C#)

// 名前空間の追加
// (なし)

// コード
private void button1_Click(object sender, EventArgs e)
{
  int v1 = 0;
  TestFunc1(v1);
  listBox1.Items.Add(v1);
  
  int v2 = 0;
  TestFunc2(ref v2);
  listBox1.Items.Add(v2);
  
  int v3;
  TestFunc3(out v3);
  listBox1.Items.Add(v3);
}

private void TestFunc1(int v1)
{
  v1++;
}

private void TestFunc2(ref int v2)
{
  v2++;
}

private void TestFunc3(out int v3)
{
  v3 = 0;
  v3++;
}

解説

TestFunc1 には、値渡しで変数を渡しています。渡された変数をメソッドの中でインクリメントしていますが、それは呼び出し元には全く影響しません。従って、出力結果は 0 となります。

TestFunc2 には、参照渡しで変数を渡しています。その際に使用しているキーワードは ref です。呼び出す側と呼び出される側双方に ref を付ける必要があります。渡された変数をメソッドの中でインクリメントしており、それが呼び出し元にも反映されます。従って、出力結果は 1 になります。

TestFunc3 にも、参照渡しで変数を渡しています。その際に使用しているキーワードは out です。呼び出す側と呼び出される側双方に out を付ける必要があります。渡された変数をメソッドの中で、一度初期化してから、インクリメントしており、それが呼び出し元にも反映されます。従って、出力結果は 1 になります。

ref と out の違いですが、変数の初期化が事前に必要かどうかが違いです。ref で変数を渡す場合には事前に初期化の必要があります。out で変数を渡す場合には、呼び出されたメソッドの中で変数の初期化を行うことができ、事前の初期化は不要です。そのために、TestFunc3 の中で一度初期化してからインクリメントしています。

結果

動作確認環境

Visual Studio 2015 Professional (C# 6.0)

-未分類