ご質問の例でいえばインスタンス上に必要な情報は
private int x;
これだけです。
プロパティ・メソッドがサイズに含まれないのはなぜなのでしょうか?
大抵のコンパイラー/インタープリタ言語でも同様なのですが、メソッドの類はインスタンス自身の内側に領域を持ってはいません。structだけでなくclassのインスタンスもそうです。
理由はどの実体であってもメソッドの実体(プロセッサーの機械語ないしは仮想マシンのIL/bytecodeの並び)は必ず同一になるからです。個々のインスタンスに依存しない同一の情報を各々のインスタンスの領域にわざわざ記録するのはメモリー領域の無駄使いでしかなく不合理です。
メンバー関数やプロパティーについて以下のコードをごらんください。
C#
1using System;
2
3public struct S {
4 public int x;
5 public void m1() { Console.WriteLine("m1: " + x); }
6 public int X
7 {
8 get { return x; }
9 set { x = value; }
10 }
11}
12
13public static class SImpl {
14 public static void m2(ref S self) { Console.WriteLine("m2: " + self.x); }
15 public static int getX(ref S self) { return self.x; }
16 public static void setX(ref S self, int value) { self.x = value; }
17}
18
19class App {
20 public static void Main() {
21 S s = new S() { x = 111 };
22 s.m1();
23 SImpl.m2(ref s);
24
25 s.X = 123;
26 Console.WriteLine("s.X = " + s.X);
27
28 SImpl.setX(ref s, 456);
29 Console.WriteLine("s.getX = " + SImpl.getX(ref s));
30 }
31}
この構造体はm1というメソッド、Xというプロパティーを持ってますが、SImplにあるm2, getX, setXを用いるとm1やXを使用するのとまったく同じことができていることがおわかりでしょか?
実はコンパイラーはm1やXをちょうどこんな雰囲気に展開してくれているのです。
そのためSの領域自体の中にはxというフィールドしか必要なく、当然ながらSizeOfも4を返すというわけです。
ソフトウェアはどんなものであれ「合理的」に設計されています。プログラムの実行効率(メモリー量やスピード)に大きな影響を及ぼす言語処理ソフトウェア(コンパイラーやランタイム)では特に効率に関する合理性の追求が顕著であり、常に可能な限り最高の効率を目指して設計されているのが普通です。
アプリケーションを書く上では仕様書を参照し「どういう仕様であるか」を知っていさえすれば充分と言えますが、もう少し突っ込んで低水準な言語処理系の本質に関して学ぶと仕様の根拠が見えてくることがあります。自分はC++に初めて触れたときC++がvirtualなメンバー関数をどのようにして実現しているかコンパイルされたコードを観察して「うーむ、なるほどうまいこと考えるものだ」と感心したことを覚えています。こういうことを少し学んでおくと「なぜこういう仕様になっているか」「何に気を付けなければならないか」がより深く把握できる気がします。
そういう意味で質問者さんが「実際にサイズがどうなるか」を調べたり「それが何故か」を考えておられるのは価値あることだと思いました。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/02 06:24 編集
2019/05/02 06:30