classとstruct

この週末、classとstructについて考えていたがとってもモヤモヤしている。
現段階では、うまく結論付けることができなかった。
とりあえずわかったことをメモっておく。

オブジェクトの比較

                                                        • -
struct(System.ValueTypeを継承)
                                                        • -
● Equals System.ValueType.Equals()により、各メンバのEqualsを呼び出す (リフレクションを使用している。高速化したければ自分でoverrideしろとのこと) ● == デフォルトでは定義されていない ※自分で定義することは可能 ● System.ValueType.ReferenceEquals ポインタの比較を行う
                                                        • -
class
                                                        • -
● Equals overrideされたメソッドに従う overrideしていなければobject.Equalsつまりポインタの比較を行う ● == overrideされたメソッドに従う されていない場合、ポインタの比較(Equalsは呼び出されない) ※stringの場合はoverrideされているため値の比較を行う ● System.Object.ReferenceEquals ポインタの比較を行う

【結論】
ポインタの比較をしたい場合はSystem.Object.ReferenceEqualsを使用する
それ以外の比較はoverrideによって変更可能なため値の比較かポインタの比較か
わからない

classとstructの使い分け

【問題】ユーザー定義型を作成する際にクラスと構造体をどう使い分けるか?
比較の種類(値の比較orポインタの比較)で使い分けるか?
→比較の種類はEqualsのoverrideで決まる。クラス、構造体の使い分けとは無関係
例)System.String はクラスであるがEqualsでは値の比較を行っている


他にはパフォーマンスぐらいしか思いつかない
今のところパフォーマンスが問題になることはないのでstructの使用は見送ることにする

C++との比較

[C++のコード]
void Function( Hoge hoge ) {
...
}
void Function( Hoge* hoge ) {
...
}

これがC#だと(ポインタ型がないために)同じコードになってしまう

[C#のコード]
void Function( Hoge hoge ) {
...
}

値型なのか参照型なのかはHogeの定義を見ないとわからない
そのため値/参照型を勘違いしているとひどい目(バグ)にあう