(C#)値渡し、参照渡し、参照値渡し
自分の理解なので、間違ってる部分もあると思いますが、
普段のコーディングの際はこんなイメージで変数を操作しています。
目次
値渡し
基本型
のクラスを扱うとき。変数の中に直接データが入ってるイメージ。
var a = 1;
var b = a;
このときはこんな感じのイメージ。
変数a
に1
が入り、その1
が変数b
にもコピーされる。
変数B
がどんな操作しても変数A
側に影響はない。
参照渡し
ref
やin
、out
を使用して扱う渡し方。
Java
ではこうした参照渡しはできず、基本型
と参照型
の値を渡している(参照型の値渡し)。
普段Java
の参照型
の話をするときは、後述の参照値渡し
みたいに呼んでいます。
var a = new instanceA(); ref var b = ref a;
変数
のメモリ番地をコピーするイメージ。なので変数B
の操作は変数A
の操作と同じ。
変数A
はインスタンスA
を見ている。
変数B
は変数A
を見ている。
なので、変数B
を操作すると、変数A
を通してインスタンスA
を操作できて、
変数B
で見るインスタンス
を変更しちゃうと、変数A
側も切り替わってしまう。
(見るインスタンスを変更する
という操作を変数A
で行ってしまうイメージ。)
参照渡しのメリットとしては、基本型
のデータをコピーせず渡せることがあげられると思います。
(たぶん他にもたくさんあります…)
例えば構造体
をただ参照したいだけなのに、何度も値渡し
してしまうと、コピーされて無駄な処理をされてしまう。
けど参照渡し
で参照できるならそれが回避できる、という具合。
参照値渡し(つまり参照型の値渡し)
参照型
のクラスを操作するときの以下のような操作。
var a = new instanceA();
var b = a;
変数A
にはインスタンスA
の場所の値
が入っていて、
変数B
にはその場所の値
がコピーされてくる。(場所の値
の値渡し
)
変数B
はインスタンスA
を操作できるが、
見るインスタンス
を変更しても、変数A
はインスタンスA
を見ているまま。
参考
参照渡し - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
構造体 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
C# 7 の新機能 - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
もう参照渡しとは言わせない 2018 冬 / Do not let anyone say "pass by reference" - Speaker Deck