2010-07-12 25 views
27

Tôi rất thích thú với một số lựa chọn thiết kế ngôn ngữ C#. Có một quy tắc trong C# spec mà cho phép sử dụng các nhóm phương pháp như những biểu hiện của is điều hành:C# Thiết kế ngôn ngữ: nhóm phương thức bên trong toán tử `is`

class Foo { 
    static void Main() { if (Main is Foo) Main(); } 
} 

Điều kiện trên luôn luôn là sai, như thông số kỹ thuật cho biết:

7.10.10 Các là nhà điều hành

Nếu E là nhóm phương pháp hoặc chữ rỗng, nếu loại E là loại tham chiếu hoặc loại có thể loại bỏ và giá trị của E là null, kết quả là sai.

Câu hỏi của tôi: mục đích/điểm/Lý do của việc cho phép sử dụng các yếu tố ngôn ngữ C# không có đại diện trong thời gian chạy CLR như nhóm phương pháp bên trong như vậy "runtime" nhà điều hành như is là gì?

+2

+1 _no đầu mối _... – SLaks

+0

Đó là ... cảnh quan tuyệt đẹp. Phần trên toán tử 'as' không đề cập đến các nhóm phương thức. –

+0

@Tim: Nhưng toán tử "as" được định nghĩa là đường cú pháp cho kết hợp các phôi, toán tử điều kiện và toán tử "is", vì vậy toán tử "as" không cần phải đề cập đến các nhóm phương thức. –

Trả lời

21

mục đích/điểm/lý do cho phép sử dụng phần tử ngôn ngữ C# không có biểu diễn thời gian chạy trong CLR như nhóm phương pháp bên trong toán tử "thời gian chạy" như thế nào?

Lưu trữ ghi chú thiết kế ngôn ngữ không đề cập đến lý do quyết định này được đưa ra, do đó, bất kỳ phỏng đoán nào cũng sẽ là phỏng đoán. Họ đề cập rằng nếu kết quả của "là" có thể được xác định tĩnh để luôn luôn đúng hoặc sai, rằng nó được xác định như vậy và đưa ra một cảnh báo. Có vẻ hợp lý rằng điều này có thể đơn giản là một lỗi.

Lý do phổ biến nhất để chuyển những gì có thể đúng là lỗi thành cảnh báo (hoặc đơn giản là cho phép) là do giảm gánh nặng khi nhà sản xuất chương trình tự động tạo mã. Tuy nhiên, tôi không thấy một kịch bản thực sự hấp dẫn ở đây.

CẬP NHẬT:

Tôi vừa kiểm tra đặc tả C# 1.0. Nó không có ngôn ngữ này. Nó không nói bất cứ điều gì về null hoặc đối số nhóm phương thức. Và tất nhiên nó không nói gì về chuyển đổi nhóm phương pháp bởi vì trong C# 1.0 không có chuyển đổi nhóm phương pháp ngầm; bạn phải gọi một cách rõ ràng "new D (M)" nếu bạn muốn chuyển đổi phương thức M thành delegate type D.

Điểm sau này là lý do cho "M là D" trả về false thay vì đúng; Bạn không thể nói một cách hợp pháp "D d = M;" vậy tại sao "M là D" là đúng?

Tất nhiên trong C# 2.0 điều này có ý nghĩa ít hơn, vì bạn có thể nói "D d = M;" trong C# 2.0.

Tôi cũng chỉ hỏi một trong những người có mặt khi toán tử "is" được thiết kế và anh ta không có ký ức nào về việc quyết định câu hỏi này theo cách này hay cách khác. Nghi ngờ của ông là thiết kế ban đầu của toán tử "is" không đưa ra bất kỳ lỗi nào, chỉ cảnh báo, và tất cả văn bản trong đặc tả về việc phải làm gì với các nhóm phương thức và null và không được thêm vào sau, cho Phiên bản C# 2.0 của spec, và dựa trên những gì trình biên dịch thực sự đã làm.

Tóm lại, có vẻ như đây là một lỗ thiết kế trong C# 1.0 đã được ghi lại khi thông số được cập nhật cho C# 2.0. Nó không giống như hành vi cụ thể này đã được mong muốn và cố tình thực hiện.

Lý thuyết này được củng cố bởi thực tế là các phương thức ẩn danh do tạo ra lỗi khi được sử dụng làm đối số cho "là" trong C# 2.0. Nó sẽ không phải là một thay đổi phá vỡ để làm như vậy, nhưng nó sẽ là một thay đổi phá vỡ để làm cho "M là D" đột nhiên bắt đầu trở lại đúng hoặc là một lỗi.

THÔNG TIN THÊM:

Trong khi điều tra điều này, tôi đã học được điều gì đó thú vị. (Đối với tôi.) Khi tính năng được thiết kế ban đầu, thiết kế cho phép hoặc là tên của một loại, hoặc đối tượng Kiểu làm đối số bên phải cho "là". Ý tưởng đó đã bị bỏ rơi trước khi C# 1.0 được vận chuyển.

3

Trước hết là một phương pháp không phải là một loại, MSDN nêu rõ như sau:

là nhà điều hành is sử dụng để kiểm tra liệu kiểu thời gian chạy của một đối tượng tương thích với một loại nhất định

Ví dụ

public static void Test (object o) 
{ 
    Class1 a; 

    if (o is Class1) {} 
} 

From MSDN:

An là biểu hiện về true nếu cả hai điều kiện sau đây được đáp ứng:

  • biểu hiện không phải là null.
  • biểu thức có thể được truyền để nhập. Nghĩa là, một biểu thức truyền của biểu mẫu (loại) (biểu thức) sẽ hoàn thành mà không cần ném một ngoại lệ. Để biết thêm thông tin, xem 7.6.6 Biểu thức truyền.

Vì vậy, lý do cho ví dụ của bạn là vùng đất giả ở điểm thứ hai, nó phải được truyền cho một loại cụ thể.

Tôi hy vọng tôi không hiểu sai câu hỏi.

+1

Câu hỏi đặt ra là, tại sao không phải là 'Chính là Class1' một lỗi trình biên dịch? – SLaks

+0

@SLacks: Có lẽ chúng ta nên sử dụng Reflector để điều tra thêm về điều này. – Andreas

+0

@SLaks, sử dụng ReShaper Tôi nhận được cảnh báo với thông báo này: "Biểu thức đã cho không bao giờ được cung cấp một loại". Đang kiểm tra với Reflector ngay bây giờ .. –

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