構造体とクラス
こういった話が。→ Design Guidelines– Classes vs. Structures
C# で、構造体とクラスの使い分けはどうするの?ということで、以下のような記述が。
- Consider defining a structure instead of a class if instances of the type are small and commonly short-lived or are commonly embedded in other objects.
- Do not define a structure unless the type has all of the following characteristics:
- It logically represents a single value, similar to primitive types (integer, double, and so on).
- It has an instance size smaller than 16 bytes.
- It is immutable.
- It will not have to be boxed frequently.
これ、最近は MS から出てるガイドライン含めよく見る文面で、荒く訳すと:
- クラスではなくて構造体の利用を考慮する場面: 小さくて、寿命が短いか、他のオブジェクトに埋め込んで使う場合に
- 以下の条件全てを満たす場合に限り構造体を使う
- 論理的に単一の値を表現する、(整数、浮動小数点数などの)組み込み型に似た型
- インスタンスのサイズが16バイト以下
- 不変(コンストラクターで値を初期化して移行、プロパティの書き換えなどをしない)
- 頻繁にボックス化されない
この条件満たすことってあんまりないんですよね。パッと思いつくのだと以下のような:
- 数学で使う複素数、有理数、3次元ベクトルとかその手のものとか
- 内部データとしては何かのハンドル値持ってるだけの型とか
- 「ちょっと複雑な enum」みたいな型とか
こういう条件が課されている理由は、以下のような感じですかね。
- 論理的に単一の値:
- ユーザー定義型と組み込み型との一貫性?
- 組み込み型で値型なものって、数値系のものしかないわけで
- 16バイト以下、低頻度でボックス化:
- 効率の問題
- 間接参照のコスト下げれても、コピーのコスト大きかったら本末転倒
- ボックス化しまくるくらいなら最初から参照型で
- 不変(immutable):
- 例えば、Center を構造体のプロパティとして、circle.Center.X = 10; みたいなコードは書けない(X が set アクセサ持ってても無理)
- 同上、var p = circle.Center; p.X = 10; みたいなコード書いても circle.Center.X が書き換わらない
- クラスと構造体でこの辺りの挙動全然変わるけど、利用側でぱっと見、構造体なのかクラスなのか区別つかないし(IDE 前提で、var のところにカーソル持っていけばわかりますけど)
- ↑の人的エラー回避のために、var p = circle.Center; circle.Center = new Point(10, p.Y); みたいなのを強要したい
- 上記の「論理的に単一の値」を満たすなら、不変(コンストラクター以外で値を書き換えられない)で困ることそうないと思うし
コメントを残す