++C++; // 未確認飛行 C ブログ

http://ufcpp.net/

構造体とクラス

leave a comment »

こういった話が。→ 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); みたいなのを強要したい
    • 上記の「論理的に単一の値」を満たすなら、不変(コンストラクター以外で値を書き換えられない)で困ることそうないと思うし

Written by ufcpp

2010年9月15日 @ 07:12

カテゴリー: C#

コメントを残す