2011-04-18 11 views
5

私はJag ReeghalのブログでThis Articleを読んでいました。彼が示唆していたことは、実際にはオブジェクトイニシャライザを使用することと同じではないようでした。それから、私は本当に分かっていないことに気付きました。イニシャライザがスローするとオブジェクトが構築されますか?

オブジェクト初期化子を使用してオブジェクトが構築され、それらの初期化子の1つがスローされます(おそらくNull参照例外)...実際に構築されるオブジェクトですか?これは基本的にコンストラクタにスローされる例外のようなものですか?オブジェクトが完全に構築され、初期化されていますか?

答えて

3

オブジェクトはこのようなものとして実装されます。

Foo temp = new Foo(); 
temp.Property1 = 5; 
x = temp; 

あなたが見ることができるようにオブジェクトが作成された後、initiallizerのプロパティが設定されている、しかし、変数が設定されていませんすべてプロパティが設定されているので、例外にスローされると、例外がキャッチされても構築されたオブジェクトは失われます(変数はnullまたはそれ以前の値のままです)。

+0

異なるものの、結果はコンストラクタが同じである場合と同じです。だから、Jagの勧告が本当に同じではないという私の考えは正しい。 –

+0

結果はほとんど同じです。例外の後にメモリに残っているものに違いがあるかもしれません。 JagはReSharperが10個のプロパティにイニシャライザの提案を制限することを推奨しています。そうしないと、コードの1行で多くのことが起こっているとデバッグするのが難しくなります。 –

1

オブジェクトは構築されますが、初期化は完了しません。初期化は単なるコンパイラのトリックです。生成されたILを見ると、どちらの場合も同じように見えます。ブログ投稿は、例外がどの行にあるのかを伝えるのが難しいと訴えていますが、個人的には難しくありませんでした。 var x = new Foo { Property1 = 5};のような文initilizer

2

最初に完全に構​​築されてから初期化されます。ただし、例外がスローされた場合は、そのようなオブジェクトへの参照を取得することはありません。コンパイラは、参照が適切に初期化されたオブジェクトのみを参照できるようにします。これを保証するために一時的に使用します。

は、したがって、たとえば、このコード:

var obj = new Model { 
    FirstName = reader[0].ToString(), 
    LastName = reader[1].ToString(), 
    Age = Convert.ToInt32(reader[2].ToString()) 
}; 

がにコンパイラによってリライトされます。

var temp = new Model(); 
temp.FirstName = reader[0].ToString(); 
temp.LastName = reader[1].ToString(); 
temp.Age = Convert.ToInt32(reader[2].ToString()) 
var obj = temp; 
0

はあなたのすべてのコンパイル済みILは常に同じではありません注意する必要があります!

違いは、デバッグ/リリースのビルド構成です。

あなたが私を信じていないと思われたら、リフレクターを見てください.....

関連する問題