値・参照同士の比較


C#の変数型には値型と参照型の2種類があることはみなさんご存知だと思います。
その2つの扱いについて少しまとめてみました。

おさらい

値型

値型は数値型や構造体(struct)によくあるもので、引数の指定とかするとデータが毎回コピーされます。
そのため、引数の指定にでかい構造体を指定するようにすると、ものすごいコストがかかるようになります。

参照型

参照型はいわゆるポインター。引数の指定とかではメモリのアドレスが渡されるだけでデータはメモリ上のどこかに存在します。
なので極端な話、1MBとかのデータを引数で渡すときも参照としてわたしてあげると、実際に渡されるデータは1,2バイトです。

文字列型について

文字列型は、一応参照型なのですが結構特殊な存在で、文字列を操作するときに毎回コピーされてから処理されます。
つまりは参照型・値型の両方を持ち合わせた存在だと言えます。

逆にstring型ではなくStringBuilder型を使うことで完全な参照型にしてあげることもできます。

ボクシング(Boxing)

もともと値型であるデータを、一応程度の参照型にしてあげることもできます。
やり方は単純で、データをobjectに変換してあげるだけ。

ただ、これにも問題があり、巨大な構造体をボクシングするのはいいのですが、データを取り出すたびに毎回、元の型に変換して上げる必要があるため、かなりコストの高い処理といえます。

ちなみに引数で値型を参照渡しする場合はrefをつけてあげるだけです。

比較について

比較は引数に渡される時と同じ状態で比較されます。つまり、値型はデータを比較、参照型はアドレス同士で比較するわけです。

値型の場合

普通の数値型で考えると簡単ですね。100と200で比較すれば当然falseになります。

この、データをそのまま比較するということでポイントで、構造体でも同じように、中身の値が同じなら別のインスタンスでもtrueになります。

参照型の場合

さて、問題の参照型。問題というほどでもないですが…初心者が陥りやすい

こちらの場合は、別のインスタンスなら内容が同じいでもfalseになります。なぜならアドレスを比較しているから。
例えば、これは別インスタンスのためfalseになります。

あと、これはボクシングした値型にも同じように言えます。

こちらもfalseとなります。なぜ?それはそれぞれの100を各自でボクシングしたからアドレスが違うのです。

 

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">