Trình biên dịch C # yêu cầu rằng bất cứ khi nào một loại tùy chỉnh xác định toán tử ==
, nó cũng phải xác định !=
(xem tại đây ).
Tại sao?
Tôi tò mò muốn biết lý do tại sao các nhà thiết kế nghĩ rằng nó cần thiết và tại sao trình biên dịch không thể mặc định triển khai hợp lý cho một trong hai toán tử khi chỉ có các toán tử khác hiện diện. Ví dụ, Lua cho phép bạn chỉ xác định toán tử đẳng thức và bạn nhận được cái khác miễn phí. C # có thể làm tương tự bằng cách yêu cầu bạn xác định == hoặc cả hai == và! = Và sau đó tự động biên dịch toán tử! = Như !(left == right)
.
Tôi hiểu rằng có những trường hợp góc kỳ lạ trong đó một số thực thể có thể không bằng nhau hoặc không bằng nhau, (như của IEEE-754 NaN), nhưng những trường hợp đó có vẻ như là ngoại lệ, không phải là quy tắc. Vì vậy, điều này không giải thích tại sao các nhà thiết kế trình biên dịch C # đưa ra ngoại lệ quy tắc.
Tôi đã thấy các trường hợp tay nghề kém trong đó toán tử đẳng thức được xác định, thì toán tử bất đẳng thức là một bản sao dán với mỗi và mọi so sánh đảo ngược và mọi && chuyển sang một | | (về cơ bản, bạn nhận được điểm ... (a == b) được mở rộng thông qua quy tắc của De Morgan). Đó là thực tế kém mà trình biên dịch có thể loại bỏ theo thiết kế, như trường hợp của Lua.
Lưu ý: Việc giữ tương tự cho các toán tử <> <=> =. Tôi không thể tưởng tượng các trường hợp bạn sẽ cần xác định những điều này theo những cách không tự nhiên. Lua cho phép bạn chỉ xác định <và <= và định nghĩa> = và> một cách tự nhiên thông qua phủ định của trình định dạng. Tại sao C # không làm như vậy (ít nhất là 'theo mặc định')?
BIÊN TẬP
Rõ ràng có những lý do hợp lệ để cho phép lập trình viên thực hiện kiểm tra sự bình đẳng và bất bình đẳng theo cách họ muốn. Một số câu trả lời chỉ ra những trường hợp có thể tốt.
Tuy nhiên, hạt nhân của câu hỏi của tôi là tại sao điều này bắt buộc phải có trong C # khi thường nó không cần thiết về mặt logic ?
Nó cũng trái ngược với các lựa chọn thiết kế cho các giao diện .NET như Object.Equals
, IEquatable.Equals
IEqualityComparer.Equals
trong đó việc thiếu NotEquals
đối tác cho thấy khung công tác coi !Equals()
các đối tượng là không đồng đều và đó là điều đó. Hơn nữa, các lớp như Dictionary
và các phương thức như .Contains()
phụ thuộc hoàn toàn vào các giao diện đã nói ở trên và không sử dụng trực tiếp các toán tử ngay cả khi chúng được định nghĩa. Trong thực tế, khi ReSharper tạo ra các thành viên bình đẳng, nó xác định cả hai ==
và !=
về mặt Equals()
và thậm chí chỉ khi người dùng chọn tạo các toán tử. Các toán tử đẳng thức không cần thiết bởi khung để hiểu sự bình đẳng của đối tượng.
Về cơ bản, .NET framework không quan tâm đến các toán tử này, nó chỉ quan tâm đến một vài Equals
phương thức. Quyết định yêu cầu cả hai toán tử == và! = Được xác định song song bởi người dùng hoàn toàn liên quan đến thiết kế ngôn ngữ và không liên quan đến ngữ nghĩa đối với .NET.