Giản từ this question và đã thoát khỏi khả năng ảnh hưởng đến từ LinqPad (không offsensive), một giao diện điều khiển ứng dụng đơn giản như thế này:nhóm phương pháp Implicit chuyển đổi Gotcha (Phần 2)
public class Program
{
static void M() { }
static void Main(string[] args)
{
Action a = new Action(M);
Delegate b = new Action(M);
Console.WriteLine(a == b); //got False here
Console.Read();
}
}
Các "false" Kết quả từ các nhà điều hành ceq
trong CIL của mã ở trên (truy cập câu hỏi gốc để biết chi tiết). Vì vậy, câu hỏi của tôi là:
(1) Tại sao ==
đang dịch sang ceq
thay vì call Delegate Equals
?
Ở đây tôi không quan tâm đến (un) gói giữa Đại biểu và Hành động. Cuối cùng, khi đánh giá a == b
, một là loại Action
trong khi b là Delegate
. Từ spec:
7.3.4 hành Binary quá tải độ phân giải
Một hoạt động có dạng x op y, trong đó op là một nhà điều hành nhị phân overloadable, x là một biểu hiện loại X, và y là một biểu thức loại Y, được xử lý như sau:
• Tập hợp các toán tử do người dùng xác định do X và Y cung cấp cho toán tử vận hành op (x, y) được xác định. Bộ này bao gồm các liên kết của các toán tử ứng cử viên được cung cấp bởi X và các ứng cử viên toán tử do Y cung cấp, mỗi xác định sử dụng các quy tắc của §7.3.5. Nếu X và Y là cùng một loại hoặc nếu X và Y có nguồn gốc từ loại cơ sở chung là thì các toán tử ứng viên được chia sẻ chỉ xuất hiện trong kết hợp được đặt một lần.
• Nếu tập hợp các toán tử do người dùng xác định người dùng không phải là trống, thì điều này sẽ trở thành tập hợp toán tử ứng viên cho hoạt động . Nếu không, toán tử nhị phân được xác định trước op triển khai, bao gồm các biểu mẫu được dỡ bỏ của chúng, trở thành tập hợp các toán tử ứng cử viên cho hoạt động này. Việc triển khai được xác định trước của một toán tử đã cho được xác định trong mô tả của toán tử (từ 7,8 đến §7,12).
• Các quy tắc giải quyết tình trạng quá tải của §7.5.3 được áp dụng cho các tập hợp các toán ứng cử viên để lựa chọn các nhà điều hành tốt nhất đối với danh sách đối số (x, y) với, và điều hành này trở nên kết quả của quá trình giải quyết quá tải. Nếu độ phân giải quá tải không chọn được một toán tử tốt nhất, một lỗi thời gian ràng buộc sẽ xảy ra.
7.3.5 Ứng viên điều hành người dùng định nghĩa
Cho một loại T và một op điều hành hoạt động (A), nơi op là một nhà điều hành overloadable và A là một danh sách đối số, các thiết lập của ứng cử viên khai thác người dùng định nghĩa được cung cấp bởi T cho nhà điều hành op (A) được xác định như sau:
• Xác định loại T0. Nếu T là một loại nullable, T0 là loại cơ bản của nó, nếu không T0 bằng T.
• Đối với tất cả các tờ khai hành op trong T0 và tất cả các nâng hình thức khai thác như vậy, nếu ít nhất một nhà điều hành được áp dụng (§7.5.3.1) đối với danh sách đối số A, sau đó tập hợp các toán tử ứng cử viên bao gồm tất cả các toán tử áp dụng như vậy trong T0.
• Nếu không, nếu T0 là đối tượng, tập hợp toán tử ứng viên sẽ trống.
• Nếu không, tập hợp toán tử ứng cử viên do T0 cung cấp là tập hợp của toán tử ứng cử viên được cung cấp bởi lớp cơ sở trực tiếp T0 hoặc lớp cơ sở hiệu quả T0 nếu T0 là tham số kiểu.
Từ spec, a và b có một lớp cơ sở cùng Delegate
, rõ ràng các quy tắc điều hành ==
quy định tại Delegate
nên được áp dụng ở đây (các toán tử == gọi Delegate.Equals cơ bản). Nhưng bây giờ có vẻ như danh sách ứng cử viên của các toán tử do người dùng xác định trống và cuối cùng là Object ==
được áp dụng.
(2) Nên (không) mã FCL tuân theo thông số ngôn ngữ C#? Nếu không, câu hỏi đầu tiên của tôi là vô nghĩa bởi vì một cái gì đó được điều trị đặc biệt. Và sau đó chúng tôi có thể trả lời tất cả những câu hỏi này bằng cách sử dụng "oh, đó là một điều trị đặc biệt trong FCL, họ có thể làm điều gì đó mà chúng tôi không thể làm. Thông số này dành cho các lập trình viên bên ngoài, đừng ngốc nghếch".
Đó là lý do tại sao tốt nhất nên sử dụng 'Bằng’ khi mong đợi ngữ nghĩa loại giá trị. Bởi vì (có khả năng) quá tải nhà điều hành bị hỏng. – Groo
@Groo: Chính xác. Và bằng cách tôi nhận được cảnh báo biên dịch cho mã trong câu hỏi 'Có thể so sánh tham chiếu không mong muốn; để so sánh giá trị, hãy bỏ phía bên phải để nhập 'System.Action''. –
Đó chắc chắn là để làm với việc xử lý đặc biệt của đại biểu nói chung, như cố gắng điều tương tự với một hệ thống phân cấp lớp người dùng định nghĩa phương thức '==' tùy chỉnh – AakashM