(C#)値渡し、参照渡し、参照値渡し

f:id:canning:20190428093658p:plain:w600

自分の理解なので、間違ってる部分もあると思いますが、
普段のコーディングの際はこんなイメージで変数を操作しています。

目次


値渡し

基本型のクラスを扱うとき。変数の中に直接データが入ってるイメージ。

var a = 1;
var b = a;

このときはこんな感じのイメージ。

f:id:canning:20190428094150p:plain:w600

変数a1が入り、その1変数bにもコピーされる。
変数Bがどんな操作しても変数A側に影響はない。

参照渡し

refinoutを使用して扱う渡し方。
Javaではこうした参照渡しはできず、基本型参照型の値を渡している(参照型の値渡し)。
普段Java参照型の話をするときは、後述の参照値渡しみたいに呼んでいます。

var a = new instanceA();
ref var b = ref a;

f:id:canning:20190428102959p:plain:w600

変数のメモリ番地をコピーするイメージ。なので変数Bの操作は変数Aの操作と同じ。
変数AインスタンスAを見ている。
変数B変数Aを見ている。
なので、変数Bを操作すると、変数Aを通してインスタンスAを操作できて、
変数Bで見るインスタンスを変更しちゃうと、変数A側も切り替わってしまう。
見るインスタンスを変更するという操作を変数Aで行ってしまうイメージ。)

f:id:canning:20190428103233p:plain:w600


参照渡しのメリットとしては、基本型のデータをコピーせず渡せることがあげられると思います。
(たぶん他にもたくさんあります…)

例えば構造体をただ参照したいだけなのに、何度も値渡ししてしまうと、コピーされて無駄な処理をされてしまう。
けど参照渡しで参照できるならそれが回避できる、という具合。

参照値渡し(つまり参照型の値渡し)

参照型のクラスを操作するときの以下のような操作。

var a = new instanceA();
var b = a;

変数AにはインスタンスA場所の値が入っていて、
変数Bにはその場所の値がコピーされてくる。(場所の値値渡し

f:id:canning:20190428105925p:plain:w600

f:id:canning:20190428105944p:plain:w600

変数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