C#における直接渡しと参照渡しについて調べてまとめた

7月 21, 2024

関数に引数として渡したオブジェクトに関数内で変更を加えた時に変更がどこまで及ぶかが分からなかった。

なので、まとめておく。

そもそも直接渡しと参照渡しって何?

まずはこの2つがどういうものかを説明しておきます。

前提として以下のことを理解してください。

変数を定義するとメモリ上に領域を確保し、変数と領域をユニークなIDで紐づけています。変数に値を代入すると確保した領域にその値を保存します。

具体的に説明すると

int a;

と記述するとメモリ上に領域を確保し、その領域と変数を「123480912」みたいなID で紐づけます。

続けて

a = 1;

と記述するとID「」に紐づいた領域に1を格納します。その状態で

Debug.Log(a);

と記述するとコンピューターは

aってなんだ?

「123480912」に紐づいた領域に確保されている値か!

うんうん、1だね。

となります。

直接渡しとは

ユニークなIDに紐づいた値を渡す処理

以下のコードはPlus関数内で引数に1を加算しています。値だけを渡しているので、おおもとの変数aには影響が及びません。

コンピューター内では
引数に設定されている変数numは直接私に該当するから新しくメモリ上に領域をとって、新しく作ったIDで変数と紐づけしておこう。
変数numに1をプラスすればいいんだね。
numのIDはこれかー。ならここの領域に格納されている値に対して1をプラスしよう。
プラスしました。
となっています。

変数numとaは領域が異なるので、1をプラスしても変数aには何の影響もありません。なので、Do関数を実行すると最初のShowで1、次のShowで1を出力します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
    int a = 1;

    public void Plus(int num)
    {
        num += 1;
    }

    public void Show()
    {
        Debug.Log(a);
    }

    public void Do()
    {

        Show(); // 1

        Plus(a);

        Show(); // 1

    }
}

参照渡し

ユニークなIDを渡す処理

以下のコードはPlus関数内で引数に1を加算しています。ユニークなID(参照)を渡しているので、おおもとの変数aに影響します。

コンピューター内では
引数に設定されている変数numはref属性が付いているから新しく領域をとらないよー。関数を実行する時に渡された変数に紐づいたIDを参照して、そのIDに紐づいた領域に処理を施せばいいんだもん。
変数numに1をプラスすればいいんだね。
変数numは変数aのユニークIDを使えばいいんだよね。
はい、プラスしました。
となっています。

変数numとaは領域が同じなので、1をプラスすると変数aをじかに操作していることになります。なので、Do関数を実行すると最初のShowで1、次のShowで2を出力します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sample : MonoBehaviour
{
    int a = 1;

    public void Plus(ref int num)
    {
        num += 1;
    }

    public void Show()
    {
        Debug.Log(a);
    }

    public void Do()
    {

        Show(); // 1

        Plus(ref a);

        Show(); // 2

    }
}

各オブジェクトがどっちに分類されるかについて

では、具体的にどういうオブジェクトが直接渡しまたは参照渡しになるのか見ていきましょう。

値 (struct) の型の場合、値のコピーがメソッドに渡されます。 参照 (class) 型の場合、参照のコピーがメソッドに渡されます。

メソッド パラメーター

知りたいことがここにまとめられていたので、こちらを読んでください。

疑問

クラスのクラスを引数にして、変化させると元のクラスにもその変更が反映されるのかな?

Unity

Posted by admin