2013-06-27 38 views
21

Vui lòng giúp hiểu hành vi này. Khi tôi sử dụng này:Chuỗi kết nối C# khi biên dịch

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

Kết quả là false

Nhưng khi tôi sử dụng này

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

Kết quả là true

Vì vậy, tại sao a1 != a2?

+0

Tôi không biết chính xác lý do tại sao, nhưng tôi biết bạn không nên kiểm tra chất lượng chuỗi sử dụng "==" anyways. object1.equals (object2) là cách để đi với điều đó, ít nhất là để hiểu biết của tôi. Tôi đã không đăng bài này như là một câu trả lời mặc dù bởi vì nó có lẽ không trả lời câu hỏi của bạn. –

+0

Kiểm tra điều này: http://stackoverflow.com/questions/3398604/string-string-int-whats-behind-the-scene-c – Ani

+1

@Ricky Mutschlechner: AFAIK toán tử '==' == '.equals'. ;-) –

Trả lời

34

Truyền tới object buộc so sánh bình đẳng tham chiếu.

Trong trường hợp đầu tiên, hai đối tượng string khác nhau được tạo khi chạy. Vì chúng là các cá thể khác nhau nên kết quả là sai.

Trong trường hợp thứ hai, trình biên dịch chú ý rằng "string" + "1" luôn là "string1" và thực tập chuỗi và sử dụng cùng một tham chiếu ở cả hai vị trí. Vì nó là tham chiếu chuỗi giống nhau, kết quả là đúng.

+2

@OP Chỉ cần thêm vào, bạn nên luôn luôn so sánh các chuỗi với String.Equals – Mataniko

+0

+1. Tôi thích câu trả lời này. Cảm ơn :) –

+10

@Mataniko Không, bạn chỉ cần đảm bảo rằng các biến của bạn là một chuỗi loại thời gian biên dịch nếu bạn sử dụng 'toán tử =='. Chỉ sử dụng 'string.Equals' nếu một hoặc nhiều đối tượng không được gõ tĩnh vào' chuỗi' (điều này thực sự khá hiếm). – Servy

19

Có hai điều quan trọng xảy ra ở đây:

Thứ nhất, Khái niệm "string" + 1 được đánh giá tại thời gian chạy trong khi "string" + "1" được đánh giá tại thời gian biên dịch.

Thứ hai, bạn đang sử dụng so sánh tham chiếu. Các chuỗi thời gian chạy được tạo ra thực sự tham chiếu đến các đối tượng khác nhau trong khi các chuỗi tạo thời gian biên dịch tham chiếu cùng một đối tượng, do đó biểu thức đầu tiên là false và biểu thức thứ hai là true.

Nếu bạn quan tâm, IL tạo ra là:

// 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 để đăng IL: P –

+0

Gọn gàng. Hãy cẩn thận để đề cập đến cách người ta sẽ xem IL như thế này? – kenchilada

+1

@radium Cá nhân, tôi sử dụng [ILSpy] (http://ilspy.net/). –

Các vấn đề liên quan