今回は、C#の構造体の使い方やクラスとの違いについてご紹介します。
C#の構造体とは
構造体(struct)は値型として扱われ、インスタンスが代入や引数として渡される際に実体のコピーが行われます。
このため、同じ値を別の変数で扱う場合でも、片方を変更するともう片方に影響が及ぶことはありません。
メモリ上ではスタックに配置されることが多く、ガベージコレクション(GC)の対象になりにくい点も特徴です。
ただし、構造体自体が大きくなるとコピーコストが大きくなるため、使いどころを見極める必要があります。
クラスとの違い
クラス(class)が参照型として扱われるのに対し、構造体は値型として扱われます。
クラスの場合はインスタンスの実体ではなく参照をコピーするため、変数が同じオブジェクトを共有している状態です。
そのため、一方を変更すると他の変数にも変更内容が反映されます。
また、クラスは継承やポリモーフィズムが使えますが、構造体は継承ができずインターフェースの実装のみ可能です。
基本的な使い方
構造体は以下のポイントを押さえて定義することが多いです。
- 値型であるため、不変(immutable)設計が推奨
- 読み取り専用プロパティを使うと、誤った変更を防げる
- C# 10以降ではパラメータなしコンストラクタも定義可能
- 大きな構造体ではコピーコストの増大に注意
また、クラスと比較してメモリ配置やパフォーマンス特性が異なるため、用途に合わせて選択することが重要です。
実用的な具体例
次の例では、2次元座標を表す構造体とクラスを用いて違いを確認します。
Point: X = 10, Y = 20
PointClass: X = 100, Y = 20
このように、構造体はコピーが独立しているため、p2を変更してもp1には影響がありません。
クラスは同じインスタンスを共有するため、pc1とpc2のどちらを変更しても反映されることがわかります。
構造体を使用する際の注意点
構造体の利用はメリットがある一方で、いくつか注意点も存在します。
- コピーコスト:大きな構造体を頻繁にコピーするとパフォーマンス低下につながる
- 不変性の推奨:変更可能なフィールドがあると意図せぬバグが起こりやすい
- ボクシング:object型に変換するとボクシングが発生し、パフォーマンスに影響
- コンストラクタの制約:C#のバージョンによってはパラメータなしコンストラクタに注意が必要
まとめ
構造体とクラスは値型と参照型という大きな違いがあります。
用途に合わせた選択で、パフォーマンスやコードの可読性を向上させることができます。
継承の必要性やメモリ管理を考慮しながら、設計段階でどちらを使うか判断しましょう。