2013-06-27 8 views
21

この動作を理解するのを手伝ってください。私はこれを使用する場合:コンパイル中のC#連結文字列

bool a1 = (object)("string" + 1) == ("string" + 1); 

結果がfalse

あるしかし、私はこの

bool a2 = (object)("string" + "1") == ("string" + "1"); 

を使用した場合の結果は、なぜa1 != a2のでtrue

のですか?

+0

私は理由を正確に知りませんが、私はあなたがとにかく「==」を使用して文字列の品質をチェックするべきではありません知っています。 object1.equals(object2)は、少なくとも私の理解にとどまる方法です。私はあなたの質問におそらく答えないので、私は答えとしてこれを投稿しませんでした。 –

+0

これを確認してください:http://stackoverflow.com/questions/3398604/string-string-int-whats-behind-the-scene-c – Ani

+1

@Ricky Mutschlechner:AFAIK演算子 '==' == '.equals'。 ;-) –

答えて

34

objectにキャスティングすると、参照平等比較が強制されます。

最初のケースでは、2つの異なるstringオブジェクトが実行時に生成されます。それらは異なるインスタンスであるため、結果は偽です。

第2のケースでは、コンパイラはが常に"string1"になり、その文字列をインターンにして、両方の場所で同じ参照を使用することに気付きます。同じ文字列参照であるため、結果はtrueです。

+2

@OPちょうど追加するには、文字列をString.Equals – Mataniko

+0

+1と常に比較する必要があります。私はこの答えが大好きです。ありがとう:) –

+10

@Matanikoいいえ、 'operator =='を使用すると、変数がコンパイル時の型文字列であることを確認してください。 'string.Equals'を使うのは、オブジェクトのうちの1つ以上が' string'に静的に型付けされていない場合だけです(これは本当にまれです)。 – Servy

19

はここで起こって二つの重要な事柄があります:"string" + "1"はコンパイル時に評価されている間

はまず、表現"string" + 1は、実行時に評価されます。

第2に、参照の比較を使用しています。コンパイル時に生成された文字列が同じオブジェクトを参照している間、実行時に生成された文字列は実際には異なるオブジェクトを参照しているため、最初の式はfalseで、2番目の式はtrueです。

あなたが興味を持っている場合、生成されたILは次のとおりです。

// bool a1 = (object)("string" + 1) == ("string" + 1); 
// bool a2 = (object)("string" + "1") == ("string" + "1"); 

IL_0000: ldstr  "string" 
IL_0005: ldc.i4.1  
IL_0006: box   System.Int32 
IL_000B: call  System.String.Concat 
IL_0010: ldstr  "string" 
IL_0015: ldc.i4.1  
IL_0016: box   System.Int32 
IL_001B: call  System.String.Concat 
IL_0020: ceq   
IL_0022: stloc.0  // a1 
IL_0023: ldstr  "string1" 
IL_0028: ldstr  "string1" 
IL_002D: ceq   
IL_002F: stloc.1  // a2 
+3

+1を掲示するための+1 –

+0

Neat。どのようにILがこのように見えるかについて言及してください。 – kenchilada

+1

@radium個人的には、[ILSpy](http://ilspy.net/)を使用しています。 –