請幫助理解這種行爲。當我使用這個:編譯時的C#連接字符串
bool a1 = (object)("string" + 1) == ("string" + 1);
結果是false
但是,當我使用這個
bool a2 = (object)("string" + "1") == ("string" + "1");
結果是true
那麼,爲什麼a1 != a2
?
請幫助理解這種行爲。當我使用這個:編譯時的C#連接字符串
bool a1 = (object)("string" + 1) == ("string" + 1);
結果是false
但是,當我使用這個
bool a2 = (object)("string" + "1") == ("string" + "1");
結果是true
那麼,爲什麼a1 != a2
?
鑄造到object
強制引用相等比較。
在第一種情況下,會在運行時生成兩個不同的string
對象。由於它們是不同的實例,所以結果是錯誤的。
在第二種情況下,編譯器注意到"string" + "1"
總是會變爲"string1"
並實施該字符串並在兩個地方使用相同的引用。由於它是相同的字符串引用,所以結果是正確的。
有這裏發生了兩個重要的事情:
首先,表達"string" + 1
在運行時間,而"string" + "1"
是在編譯時進行計算評估。
其次,您正在使用參考比較。運行時生成的字符串實際上引用不同的對象,而編譯時生成的字符串引用相同的對象,因此第一個表達式爲false
,第二個表達式爲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
我不知道爲什麼,但我知道你不應該使用檢查字符串的質量「==」反正。 object1.equals(object2)是這樣做的方式,至少在我的理解。我沒有發佈這個答案,因爲它可能不會回答你的問題。 –
檢查此:http://stackoverflow.com/questions/3398604/string-string-int-whats-behind-the-scene-c – Ani
@Ricky Mutschlechner:AFAIK運算符'=='=='.equals'。 ;-) –