2013-06-06 14 views
11

空の構造体をC#で新しくすることは何ですか?</p> <pre><code>struct EmptyResult { } </code></pre> <p>インスタンスタイプ<code>EmptyResult</code>の変数を作成した結果がどのようなものです:あなたは、構造体を宣言した場合は

public Foo() 
{ 
    EmptyResult result; 
} 

スタックに割り当てがあると思いますか、それとも効果的にノーオペレーションですか?

+0

コンパイラがこれを最適化することを願っています。 Fooにその行にブレークポイントを設定し、ヒットしたかどうかを確認します。 – Sayse

+0

... – James

+0

「int」型の変数を作成した場合、最適化されます。おそらくもっと良い例は、構造体を関数に渡すことです。 –

答えて

9

C#コンパイラは、空の構造体に1バイトのサイズを強制します。だからクラス内またはスタック上のその構造体の任意のインスタンスは、1つのバイトを占有します

[StructLayout(LayoutKind.Sequential, Size=1)] 
private struct EmptyResult 
{ 
} 

System.Byteのインスタンスとまったく同じか:あなたは逆コンパイラで構造体を見ている場合は、これを見ることができますSystem.SByte

+1

おそらくそれはそのアドレスを取ることができるようにそうする。 –

+0

逆コンパイルする必要はありません。 'Marshal.SizeOf(typeof(EmptyResult))'を使うことができます。私はちょうどポストするつもりでしたが、遅すぎました。 –

+1

@DavidHeffernan私はあなたが正しいと確信しています - それはあなたがそのアドレスを取ることができるだけでなく、2つのインスタンスが異なるアドレスを持つように。興味深いことに、Stroustrupは空のC++構造体について言及しています(http://www.stroustrup.com/bs_faq2.html#sizeofempte)。 –

1

私はそれが非参照型の仕組みと一線を画しているスタック割り当てだと思います。

+1

しかし、構造体のサイズは0バイトです。どのように0バイトを割り当てますか? – Servy

+0

C++では、1バイトを占有します。 – aquaraga

3

フィールドがないAC#structのサイズは1です。この理由は、コンパイラが安全でないコードの&演算子を使用して構造体のアドレスを取得できる必要があるためです。

あなたの構造体型は、byte型とまったく同じ方法で処理されると思います。

1

あなたは、ILを勉強するidlasm.exeを使用する場合は、あなたがEmpty構造体のインスタンスを作成するラインで、あなたが表示されます:

.maxstack 1 
.locals init ([0] valuetype Draft.Empty e) 

をそしてEmpty構造体の定義は次のとおりです。

.class private sequential ansi sealed beforefieldinit Draft.Empty 
     extends [mscorlib]System.ValueType 
{ 
    .pack 0 
    .size 1 
} // end of class Draft.Empty 

作成時に1バイトが割り当てられ、定義ではこのタイプのサイズは1です。

そうです。スタック上に1バイトを割り当てます。

注:リリースモードでコンパイルされたアセンブリから抽出されたEmptyの定義。

+0

JIT段階では、もちろんそれを最適化することができます –

+0

@DavidHeffernan '新しいEmpty()。Equals(new Empty())'がどのようにtrueを返すか説明してください。スタックに実際のアドレスは必要ないのですか? (私は本当にJITワークフローに精通していません)。ありがとう –

+0

'Equals()'は構造体の値の等価性をチェックします。フィールドがないので、 'EmptyResult'型のオペランドに対して' s1.Equals(s2) 'は常に' true'である場合があります。 –

関連する問題

 関連する問題