2015-12-09 33 views
39

Tôi đã tìm kiếm mã nguồn của FCL và tôi đã nhầm lẫn rằng string.Equals() sử dụng Object.ReferenceEquals()Object.ReferenceEquals() sử dụng toán tử == cho jugde. Và sau đó tôi không thể tìm thấy cách toán tử == được xác định.Toán tử == được định nghĩa trong lớp "đối tượng" ở đâu?

Vậy nhà khai thác ban đầu được xác định ở đâu?

+5

Im khá chắc chắn phần của chính ngôn ngữ C# và không phải là một phần của đối tượng. – Nahum

+1

tính năng của nó bắt nguồn từ ngôn ngữ C#. ** Theo mặc định, toán tử == kiểm tra tính bình đẳng tham chiếu bằng cách xác định xem hai tham chiếu có cho biết cùng một đối tượng hay không, vì vậy các kiểu tham chiếu không cần thực hiện toán tử == để có được hàm này. ** - from [msdn] (https : //msdn.microsoft.com/en-US/library/ms173147 (v = vs.80) .aspx # Anchor_1) –

Trả lời

26

Đây là toán tử mà ngôn ngữ sử dụng để xác thực hai giá trị đó giống nhau. Khi mã của bạn được biên dịch, toán tử này sẽ được biên dịch một cách thích hợp trong CIL và sau đó khi chúng ta sẽ được CLR thực thi, hai giá trị sẽ được so sánh để được kiểm tra nếu chúng giống nhau.

Ví dụ, đây là mã CIL cho phương pháp Main:

Enter image description here

rằng trình biên dịch tạo ra cho chương trình sau đây (đó là một ứng dụng giao diện điều khiển):

class Program 
{ 
    static void Main(string[] args) 
    { 
     int a = 3; 
     int b = 4; 
     bool areEqual = a == b; 
     Console.WriteLine(areEqual); 
    } 
} 

Lưu ý Dòng IL_0007. Có một hướng dẫn ceq đã được phát ra. Đây là bạn đang tìm kiếm, toán tử ==.

Lưu ý quan trọng

này đang xảy ra khi == không bị quá tải.

17

Khi không có toán tử quá tải == (như ở đây), trình biên dịch phát ra lệnh ceq. Không còn mã C# để xem xét vào thời điểm này.

So sánh hai giá trị. Nếu chúng bằng nhau, giá trị số nguyên 1 (int32) được đẩy lên ngăn xếp đánh giá; nếu không 0 (int32) được đẩy lên ngăn xếp đánh giá.

3

Quá tải operator== trong C# là cú pháp đường để gọi hàm tĩnh. Độ phân giải quá tải, giống như tất cả độ phân giải quá tải, xảy ra dựa trên loại tĩnh tĩnh của đối tượng, không phải loại động. Chúng ta hãy nhìn vào Object.ReferenceEquals một lần nữa:

public static bool ReferenceEquals (Object objA, Object objB) { 
    return objA == objB; 
} 

Ở đây, loại tĩnh của objAobjBObject. Loại động có thể là bất kỳ thứ gì; một chuỗi, một số loại người dùng được xác định khác, bất cứ điều gì; không sao đâu. Việc xác định mà operator== được gọi là được xác định tĩnh khi chức năng này được biên dịch, vì vậy bạn luôn nhận được mặc định, không quá tải, được xây dựng trong ngôn ngữ cung cấp một. .NET chỉ có thể không có ReferenceEquals và cho phép người dùng thực hiện ((object)a) == ((object)b), nhưng có một hàm được đặt tên cụ thể để nói điều gì đang diễn ra cải thiện độ rõ ràng.

Object.Equals, mặt khác, chỉ là một chức năng ảo. Kết quả là, Equals được chọn dựa trên loại động của đối tượng ở bên trái của .Equals(, giống như bất kỳ lệnh gọi hàm ảo nào khác.

4

ceq lấy hai giá trị từ ngăn xếp và cho kết quả. Nếu giá trị kết quả là 1 thì chúng được coi là bằng nhau và 0 nếu chúng không bằng nhau.

Tuy nhiên, toán tử == không phải lúc nào cũng được dịch sang ceq. Cho dù == trong kết quả C# trong ceq phụ thuộc vào một số yếu tố khác như are data types primitives hoặc do they have custom == operators hoặc are they references.

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