2009-04-21 92 views
37

Sự khác nhau giữa a.Equals(b)a == b đối với loại giá trị, loại tham chiếu và chuỗi là gì? Nó có vẻ như là mặc dù một == b hoạt động tốt cho dây, nhưng tôi đang cố gắng để chắc chắn để sử dụng thực hành mã hóa tốt.Sự khác nhau giữa .Equals và ==

+0

Hãy xem http://stackoverflow.com/questions/144530/-or-equals –

Trả lời

34

Từ When should I use Equals and when should I use ==:

Các Bằng phương pháp chỉ là một ảo một định nghĩa trong System.Object, và ghi đè bởi bất cứ lớp chọn để làm như vậy. Toán tử == là toán tử có thể bị quá tải bởi các lớp , nhưng thường có hành vi nhận dạng .

Đối với các loại tài liệu tham khảo nơi == chưa bị quá tải, nó so sánh dù hai tài liệu tham khảo tham khảo đến cùng đối tượng - đó là chính xác những gì thực hiện của Equals làm trong System.Object.

Loại giá trị không cung cấp quá tải cho == theo mặc định. Tuy nhiên, hầu hết các loại các loại giá trị được cung cấp bởi khung cung cấp quá tải của riêng chúng. Việc thực hiện mặc định của Equals cho một loại giá trị được cung cấp bởi ValueType, và sử dụng phản ánh để làm sự so sánh, mà làm cho nó chậm hơn so với một loại cụ thể thực hiện đáng kể thường sẽ. Việc thực hiện này cũng là các cuộc gọi Bằng với các cặp tham chiếu trong hai giá trị được so sánh.

using System; 

public class Test 
{ 
    static void Main() 
    { 
     // Create two equal but distinct strings 
     string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); 
     string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'}); 

     Console.WriteLine (a==b); 
     Console.WriteLine (a.Equals(b)); 

     // Now let's see what happens with the same tests but 
     // with variables of type object 
     object c = a; 
     object d = b; 

     Console.WriteLine (c==d); 
     Console.WriteLine (c.Equals(d)); 
    } 
} 

Kết quả của chương trình mẫu ngắn này là

True 
True 
False 
True 
0

"==" là toán tử có thể bị quá tải để thực hiện các việc khác nhau dựa trên các loại được so sánh.

Các hoạt động mặc định được thực hiện bởi "==" là a.Equals(b);

Đây là cách bạn có thể quá tải toán tử này với nhiều loại chuỗi:

public static bool operator == (string str1, string str2) 
{ 
    return (str1.Length == str2.Length;) 
} 

Lưu ý rằng đây là khác biệt so với str1.Equals(str2);

lớp Derived thể cũng ghi đè và xác định lại Equals().

Theo như "thực tiễn tốt nhất", tùy thuộc vào ý định của bạn.

+0

Bạn có thể làm rõ ý nghĩa của từ "Hoạt động mặc định được thực hiện bởi" == không "là a.Equals (b)". –

+0

Nếu bạn không quá tải toán tử '==', nó thực hiện tương tự như hàm Equals(). Đối với chuỗi, nó so sánh chuỗi, đối với các loại người dùng, nó so sánh các tham chiếu. –

7

Ở mức đơn giản, sự khác biệt là phương thức được gọi. Phương thức == sẽ cố gắng ot liên kết với toán tử == nếu được định nghĩa cho các kiểu được đề cập. Nếu không có == được tìm thấy cho các loại giá trị, nó sẽ thực hiện so sánh giá trị và đối với các loại tham chiếu, nó sẽ so sánh tham chiếu. Một cuộc gọi .Equals sẽ thực hiện một công văn ảo trên phương thức .Equals.

Như những gì các phương pháp cụ thể làm, tất cả đều nằm trong mã. Người dùng có thể xác định/ghi đè các phương pháp này và làm bất cứ điều gì họ muốn. Lý tưởng nhất là phương pháp này nên tương đương (xin lỗi vì chơi chữ) và có cùng đầu ra nhưng không phải lúc nào cũng vậy.

+0

+1 Tốt để đề cập rằng Equals là một phương pháp ảo. –

7

Một khác biệt đáng kể giữa chúng là == là một nhà điều hành nhị phân tĩnh hoạt động trên hai trường hợp của một loại trong khi Equals là một ví dụ phương pháp. Lý do này quan trọng là bạn có thể làm điều này:

Foo foo = new Foo() 
Foo foo2 = null; 
foo2 == foo; 

Nhưng bạn không thể làm điều này mà không cần ném một NullReferenceException:

Foo foo = new Foo() 
Foo foo2 = null; 
foo2.Equals(foo); 
0

Đối với chuỗi bạn muốn cẩn thận so sánh cụ thể văn hóa. Ví dụ cổ điển là S kép Đức, trông giống như một b. Điều này phải khớp với "ss" nhưng không khớp với một so sánh đơn giản ==.

Để so sánh chuỗi sử dụng văn hóa nhạy cảm: String.Compare (dự kiến, giá trị, StringComparison ....) == 0? với quá tải StringComparison bạn cần.

0

Theo mặc định, cả hai ==.Equals() là tương đương nhau từ khả năng gọi .Equals() về một trường hợp null (mà sẽ cung cấp cho bạn một NullReferenceException). Tuy nhiên, bạn có thể ghi đè chức năng của chúng một cách độc lập (mặc dù tôi không chắc chắn sẽ là một ý tưởng hay trừ khi bạn đang cố gắng giải quyết những thiếu sót của một hệ thống khác), điều đó có nghĩa là bạn có thể làm cho chúng khác biệt .

Bạn sẽ tìm thấy mọi người ở cả hai bên của lối đi như một mặt để sử dụng. Tôi thích toán tử hơn là hàm.

Nếu bạn đang nói về chuỗi, tuy nhiên, bạn nên sử dụng string.Compare() thay vì một trong các tùy chọn đó.

3

Một cách đơn giản để giúp nhớ sự khác biệt là a.Equals(b) tương tự với
a == (object)b.

Phương pháp .Equals() không phải là chung và chấp nhận đối số kiểu "đối tượng" và vì vậy khi so sánh toán tử ==, bạn phải suy nghĩ về nó như thể toán hạng bên phải được truyền đến đối tượng trước.

Một ý nghĩa là a.Equals(b) sẽ gần như luôn luôn quay trở lại một số giá trị cho ab, bất kể loại (theo cách thông thường để quá tải là chỉ cần trở false nếu b là một loại unkown). a == b sẽ chỉ ném ngoại lệ nếu không có so sánh nào cho các loại đó.

6

Trong câu trả lời viết tắt nhất:

== opertator là để kiểm tra danh tính. (tức là: a == b là hai đối tượng này có cùng một đối tượng không?)

.Equals() là để kiểm tra giá trị. (ví dụ: a.equals (b) đều giữ giá trị giống hệt nhau?)

Với một ngoại lệ:
Đối chuỗikiểu giá trị được xác định trước (như int, phao vv ..),
toán tử == sẽ trả lời cho giá trị và không nhận dạng. (giống như sử dụng .Equals())

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