この動作を理解してください。これを使用する場合:
bool a1 = (object)("string" + 1) == ("string" + 1);
結果はfalse
でもこれを使うと
bool a2 = (object)("string" + "1") == ("string" + "1");
結果はtrue
それで、なぜa1 != a2
ですか?
この動作を理解してください。これを使用する場合:
bool a1 = (object)("string" + 1) == ("string" + 1);
結果はfalse
でもこれを使うと
bool a2 = (object)("string" + "1") == ("string" + "1");
結果はtrue
それで、なぜa1 != a2
ですか?
にキャストするとobject
、参照等価比較が強制されます。
最初のケースでは、実行時に 2 つの異なるstring
オブジェクトが生成されます。それらは異なるインスタンスであるため、結果は false です。
"string" + "1"
2 番目のケースでは、コンパイラは常にそうなることに気づき"string1"
、文字列をインターンして、両方の場所で同じ参照を使用します。同じ文字列参照なので、結果は true です。
ここでは、次の 2 つの重要なことが行われています。
まず、式"string" + 1
は実行時に評価され、式は"string" + "1"
コンパイル時に評価されます。
次に、参照比較を使用しています。実行時に生成された文字列は実際には異なるオブジェクトを参照しますが、コンパイル時に生成された文字列は同じオブジェクトを参照するため、最初の式は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