2017-08-29 16 views
5

Tôi đang bối rối về việc sử dụng == trong (C#) khi tôi sử dụng chuỗi chữ như ở đây:bối rối của việc sử dụng == nhà điều hành trong C#

object a="hello"; 
object b="hello"; 

so sánh a==b sẽ thành sự thật.

nhưng khi tôi sử dụng đối tượng như ở đây:

object c=new StringBuilder("hello").ToString(); 
object d=new StringBuilder("hello").ToString(); 

so sánh a==b sẽ là sai lầm.

mặc dù a,b,c,d tất cả loại System.Object trong thời gian biên dịch và == giá trị so sánh toán tử phụ thuộc vào giá trị của chúng trong thời gian biên dịch.

tôi sử dụng phương pháp mở rộng để có được loại varabiles trong thời gian biên dịch:

public static class MiscExtensions 
{ 
    public static Type GetCompileTimeType<T>(this T dummy) 
    { return typeof(T); } 
} 
+3

Đối tượng chuỗi nội bộ được so sánh với '==' làm bình đẳng tham chiếu sẽ trả về false (xem https://stackoverflow.com/questions/1766492/overloading-operator-versus-equals). –

+0

Tôi nghĩ rằng bạn đang bối rối hơn về các loại khác nhau trong C#. 'Object',' string' và 'StringBuilder' không giống nhau, đó là lý do tại sao chúng có tên khác nhau. ;) – waka

+0

câu hỏi tương tự ở đây: https://stackoverflow.com/questions/27710665/comparing-values-using-operator – Winnie

Trả lời

17
object a="hello"; 
object b="hello"; 

Dưới đây trình biên dịch tạo ra một đơn dụstring cho literal "hello". Vì vậy, ab trỏ đến cùng một ví dụ.

Trong đoạn thứ hai của bạn cd điểm đến khác nhaustring trường. Tuy nhiên

Điểm quan trọng là a == bc == d không gọi == điều hành của lớp string, nhưng tất object. Vì vậy, so sánh tham chiếu đơn giản được thực hiện, không phải là so sánh string.

+0

@mark có giao diện tài liệu chính thức. Họ nói rằng bình đẳng được thực hiện bằng cách tham khảo thay vì cho chuỗi. René Vogt đúng với câu trả lời này – OrcusZ

1

Khi bạn sử dụng chuỗi liên tục "hello" trình biên dịch sẽ tạo ra một phiên bản thực tập nội trú của chuỗi này và sử dụng giá trị này cho cả một và B.

Khi bạn sử dụng một StringBuilder và ToString hai trường hợp riêng biệt của một chuỗi có chứa "hello" sẽ được so sánh.

Nếu bạn muốn kiểm tra sự bình đẳng chuỗi, bạn nên sử dụng Equals() phương pháp

7

Lưu ý ở đây là bạn đang so sánh object và không string!

này sẽ cho đúng:

string c = new StringBuilder("hello").ToString(); 
string d = new StringBuilder("hello").ToString(); 

c == d; // true 

hay này:

var c = new StringBuilder("hello").ToString(); 
var d = new StringBuilder("hello").ToString(); 

c == d; // true 

(vì trong trường hợp này, var sẽ ngầm gõ các biến như là kết quả của biểu thức, StringBuilder.ToString(), mà là string), xem here để biết thêm thông tin


Không pha trộn object so sánh và string so sánh.

Trên trường hợp cơ bản của bạn, so sánh dẫn đến sự thật bởi vì nó thực sự là cùng một đối tượng!

Trong trường hợp thứ hai, bạn có hai câu lệnh "mới", do đó có hai trình tạo chuỗi khác nhau, tạo ra hai đối tượng chuỗi mới. Không phải cùng một đối tượng chuỗi không đổi.

So sánh được sử dụng được xác định bởi loại biến của bạn.

+1

Thêm vào câu trả lời này, đây là liên kết [giải thích từ khóa var chi tiết hơn] (https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var) – waka

+0

có, Tôi sẽ thêm một từ về điều này trong câu trả lời của tôi, cảm ơn bạn – Pac0

2

Đối với các loại tham chiếu không phải là chuỗi, == trả về true nếu hai toán hạng tham chiếu đến cùng một đối tượng.

Trong ví dụ đầu tiên:

object a="hello"; 
object b="hello"; 

mộtb điểm đến cùng một đối tượng, vì vậy họ đều bình đẳng, nhưng trong thứ hai:

object c=new StringBuilder("hello").ToString(); 
object d=new StringBuilder("hello").ToString(); 

bạn tạo hai khác nhau các phiên bản của StringBuilder: cd, vì vậy chúng trỏ tới đối tượng khác nhau và là KHÔNG bằng nhau (sai)

Thông tin chi tiết bạn có thể tìm thấy trên Microsoft Docs.

2

Từ msdn page:

Đối với các loại giá trị được xác định trước, các nhà điều hành bình đẳng (==) trả về true nếu các giá trị của toán hạng của nó đều bình đẳng, false. Để tham khảo các loại khác với chuỗi, == trả về true nếu hai toán hạng của nó tham chiếu đến cùng một đối tượng. Đối với loại chuỗi, == so sánh giá trị của các chuỗi .

Vì vậy, cả hai so sánh sẽ không bằng nhau, vì bạn đặc biệt truyền sang đối tượng thay vì chuỗi. Tuy nhiên trình biên dịch C# được tối ưu hóa và nhận ra rằng bạn đang sử dụng hai chuỗi ký tự giống hệt nhau, do đó trình biên dịch kết hợp hai chuỗi thành một đối tượng, do đó so sánh đối tượng là đúng. nhưng trình biên dịch không thể hợp nhất các trường hợp StringBuilder vì bạn đang xây dựng các đối tượng mới bằng cách sử dụng từ khóa new.

1
object a="hello"; 
object b="hello"; 

Ở đây cả a và b đều trỏ đến cùng một đối tượng. Để cụ thể họ đang chỉ vào cùng một bộ nhớ. Trong khi đó, trong ví dụ thứ hai

object c=new StringBuilder("hello").ToString(); 
object d=new StringBuilder("hello").ToString(); 

Ở đây bạn đang tạo một phiên bản mới, cụ thể là vị trí bộ nhớ thay đổi cho cả c và d. vì vậy đó là lý do a == b và c! = D.

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