Sự nhầm lẫn chính ở đây là bạn cho rằng tất cả các thư viện .NET (trong trường hợp này là Thư viện số mở rộng, không phải là một phần của BCL) được viết bằng C # tiêu chuẩn. Điều này không phải lúc nào cũng đúng, và các ngôn ngữ khác nhau có các quy tắc khác nhau.
Trong C # tiêu chuẩn, đoạn mã bạn nhìn thấy sẽ dẫn đến tràn ngăn xếp, do cách hoạt động của độ phân giải quá tải toán tử. Tuy nhiên, mã không thực sự có trong C # tiêu chuẩn - về cơ bản nó sử dụng các tính năng không có giấy tờ của trình biên dịch C #. Thay vì gọi toán tử, nó phát ra mã này:
ldarg.0
ldarg.1
ceq
ret
Vậy đó :) Không có mã C # tương đương 100% - điều này đơn giản là không thể có trong C # với loại của riêng bạn .
Ngay cả khi đó, toán tử thực tế không được sử dụng khi biên dịch mã C # - trình biên dịch thực hiện một loạt các tối ưu hóa, như trong trường hợp này, trong đó nó thay thế op_Equality
cuộc gọi chỉ bằng cách đơn giản ceq
. Một lần nữa, bạn không thể sao chép điều này trong DoubleEx
cấu trúc của riêng bạn - đó là phép thuật trình biên dịch.
Đây chắc chắn không phải là một tình huống duy nhất trong .NET - có rất nhiều mã không hợp lệ, tiêu chuẩn C #. Những lý do thường là (a) hack trình biên dịch và (b) một ngôn ngữ khác, với các hack thời gian (c) lẻ (tôi đang nhìn vào bạn , Nullable
!).
Vì trình biên dịch Roslyn C # là nguồn oepn, tôi thực sự có thể chỉ cho bạn tại nơi quyết định quá tải:
Nơi giải quyết tất cả các toán tử nhị phân
Các "phím tắt" cho các nhà khai thác nội tại
Khi bạn nhìn vào các phím tắt, bạn sẽ thấy sự bình đẳng giữa kết quả gấp đôi và gấp đôi trong toán tử kép nội tại, không bao giờ trong ==
toán tử thực được xác định trên loại. Hệ thống loại .NET phải giả vờ Double
là một loại giống như bất kỳ loại nào khác, nhưng C # không - double
là nguyên thủy trong C #.