2009-04-30 45 views
15

trong C# chính xác những gì xảy ra trong nền khi bạn so sánh với toán tử "==" trên hai đối tượng? nó có so sánh địa chỉ không? hoặc làm điều gì đó như Equals() hoặc CompareTo()?C# toán tử == làm gì chi tiết?

PS: toán tử "==" trong java là gì? nó có hoạt động giống nhau không?

+0

Chỉ cần một thông tin nhanh: nếu bạn quá tải ==, bạn cũng phải thực hiện =!. Tương tự cũng vậy cho <= and > =. – Tarik

Trả lời

24

Theo như tôi biết:

  • nó so sánh các loại giá trị bằng giá trị (bình đẳng)
  • nó so sánh các loại tài liệu tham khảo bằng cách tham khảo (identity)
  • trừ khi các nhà điều hành == bị quá tải, sau đó nó gọi đó là một.

Bằng được thực hiện trong đối tượng và cũng có thể bị ghi đè. Việc triển khai mặc định trong Object thực hiện so sánh tham chiếu cho các kiểu tham chiếu. Vì vậy, theo mặc định, Equals và == làm tương tự.

Tôi nghĩ rằng trong java bạn không thể quá tải toán tử ==. Nhưng kiến ​​thức Java của tôi khá lỗi thời.

Chỉnh sửa: Lưu ý rằng toán tử == là phương pháp tĩnh. Nó bị ràng buộc tại thời gian biên dịch, dựa trên các loại biến hoặc trường của bạn. Equals là một phương thức ảo được tìm thấy trong thời gian chạy, dựa trên các loại thời gian chạy thực tế.

+3

Câu trả lời xuất sắc; ít nhất một thiếu sót, mặc dù: http://stackoverflow.com/questions/806020/snip/806068#806068 –

+0

bạn không thể ghi đè toán tử == trong java, đối với các loại tham chiếu trong java == sẽ luôn làm tham chiếu (danh tính) so sánh. –

+1

Bạn không thể ghi đè toán tử trong C# vì chúng không phải là ảo. Bạn chỉ có thể quá tải chúng. –

4

From MSDN:

Đố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. Đối với các loại tham chiếu ngoà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 chuỗi.

3

Không ... toán tử == không phải lúc nào cũng hoạt động giống nhau trong java và trong C#.

Ví dụ: với Chuỗi; Java == so sánh các tham chiếu của các đối tượng chuỗi ... (nếu bạn sử dụng các kiểu primitve, == trong java so sánh các giá trị). Đó là lý do

// returns FALSE in JAVA 
(new String("test") == "test") 

sẽ không trở thành sự thật trong java ...

Trong C# Ngược lại, các nhà điều hành == không cư xử khác nhau trên dây. Ví dụ, nó sẽ trở lại đúng trong trường hợp sau đây:

// returns TRUE in C# 
(new String("test".ToCharArray()) == "test") 
+0

Điều này là do toán tử == không thể ghi đè trong Java, nhưng trong C#, và đó là những gì nó dành cho chuỗi. Điều này có làm cho hành vi của nhà điều hành khác nhau không? –

+0

Tôi nghĩ rằng đó là một cạm bẫy phổ biến khi bạn được sử dụng để viết phần mềm trong C# và sau đó sử dụng Java trong một dự án khác ... đó là lý do tại sao tôi muốn chỉ ra nó – Homes2001

9

Là một phần mở rộng cho Stefan's excellent answer - ngoại lệ khác là nếu toán hạng liên quan đến Nullable<T> - trong trường hợp này "nâng lên" khai thác áp dụng (14,2.7 trong ECMA 334v4):

Đối với các nhà khai thác bình đẳng == =

một hình thức dỡ bỏ của một nhà điều hành tồn tại nếu các loại toán hạng đều kiểu giá trị không nullable và nếu loại kết quả! là bool. Hình thức nâng lên được xây dựng bằng cách thêm một đơn? công cụ sửa đổi cho từng loại toán hạng. Toán tử nâng cấp xem xét hai giá trị rỗng là bằng nhau và giá trị rỗng không bằng nhau với bất kỳ giá trị không null nào. Nếu cả hai toán hạng đều không null, thì toán tử được dỡ bỏ sẽ bỏ trống các toán hạng và áp dụng toán tử cơ bản cho tạo kết quả bool.

Điều đó có nghĩa là: bởi vì có một nhà điều hành bình đẳng giữa (nói):

int i = ..., j = ...; 
bool eq = i == j; 

Do đó có một nhà điều hành ngầm của form (mặc dù thực hiện khác nhau):

int? i = ..., j = ...; 
bool eq; 
if(i.HasValue) { 
    if(j.HasValue) { // both have values; compare 
     eq = i.GetValueOrDefault() == j.GetValueOrDefault(); 
    } else { // one null; always false 
     eq = false; 
    } 
} else { // true if both null, else false 
    eq = !j.HasValue; 
} 
0

Hành vi của toán tử == phụ thuộc vào cách biến mà bạn đang áp dụng nó được khai báo (không phải trên lớp của đối tượng, tôi sẽ thêm một ví dụ).

Đối với các loại giá trị, nó sẽ so sánh các giá trị của chúng.

Đối với loại tham chiếu a == b trả về true nếu a là cùng một đối tượng với b, trừ khi toán tử == bị quá tải. Không được ghi đè như những người khác đã nói, bạn không thể ghi đè các toán tử trong C# vì chúng không phải là ảo.

object obj_a, obj_b; string str_a, str_b;

 str_a = "ABC"; 
     str_b = new string("ABC".ToCharArray()); 
     obj_a = str_a; 
     obj_b = str_b; 

     Console.WriteLine("str_a == str_b = {0}", str_a == str_b); // in string == operator is overloaded 
     Console.WriteLine("str_a.Equals(str_b) = {0}", str_a.Equals(str_b)); // string overrides Object.Euqals 
     Console.WriteLine("obj_a == obj_b = {0}", obj_a == obj_b); // in object == operator is not overloaded 
     Console.WriteLine("obj_a.Equals(obj_b) = {0}", obj_a.Equals(obj_b)); // Object.Equesl is virtual and overridden method from string will be executed. 
     Console.ReadKey(); 

Kết quả của chương trình đó là

 
str_a == str_b = True 
str_a.Equals(str_b) = True 
obj_a == obj_b = False 
obj_a.Equals(obj_b) = True