2011-02-09 25 views
18

Tôi rất vui vì C# không cho phép bạn truy cập các thành viên tĩnh như thể họ là thành viên cá thể. Điều này tránh một lỗi phổ biến trong Java:Tại sao lại hữu ích khi truy cập các thành viên tĩnh "thông qua" các kiểu kế thừa?

Thread t = new Thread(..); 
t.sleep(..); //Probably doesn't do what the programmer intended. 

Mặt khác, nó không phép bạn truy cập các thành viên tĩnh 'qua' loại có nguồn gốc. Khác với các nhà khai thác (nơi nó giúp bạn tiết kiệm từ viết phôi), tôi không thể nghĩ ra bất kỳ trường hợp nào điều này thực sự hữu ích. Trong thực tế, nó tích cực khuyến khích sai lầm như:

// Nasty surprises ahead - won't throw; does something unintended: 
// Creates a HttpWebRequest instead. 
var ftpRequest = FtpWebRequest.Create(@"http://www.stackoverflow.com"); 

// Something seriously wrong here. 
var areRefEqual = Dictionary<string, int>.ReferenceEquals(dict1, dict2); 

Cá nhân tôi giữ cam kết lỗi tương tự hơn và hơn khi tôi đang tìm cách của mình thông qua các API không quen thuộc (Tôi nhớ bắt đầu với cây biểu thức; tôi nhấn BinaryExpression. trong trình soạn thảo và tự hỏi tại sao IntelliSense lại cung cấp cho tôi MakeUnary làm tùy chọn).

In (thiển cận) tôi ý kiến, tính năng này:

  1. Không giảm tính cách rườm rà; lập trình viên phải chỉ định một tên kiểu một cách này hay cách khác (trừ các toán tử và các trường hợp khi một người đang truy cập các thành viên tĩnh kế thừa của kiểu hiện hành).
  2. Khuyến khích các lỗi/mã gây hiểu lầm như mã ở trên.
  3. Có thể đề xuất với lập trình viên rằng các phương pháp tĩnh trong C# thể hiện một số loại 'đa hình', khi chúng không.
  4. (Dân tộc thiểu số) Giới thiệu các khả năng hồi phục không thể mong đợi khi biên dịch lại.

(IMO, các nhà khai thác là một trường hợp đặc biệt mà bảo đảm cuộc thảo luận riêng của họ.)

Cho rằng C# là bình thường một "hố của thành công" ngôn ngữ, tại sao tính năng này tồn tại? Tôi không thể thấy các lợi ích của nó (ngoài 'khả năng phát hiện', mà có thể luôn được giải quyết trong IDE), nhưng tôi thấy rất nhiều vấn đề.

+3

Hoặc, tệ hơn, 'UTF8Encoding.ASCII'. – SLaks

+1

Tôi đồng ý rằng nó có thể hơi gây nhầm lẫn, nhưng nó phù hợp với nguyên tắc mà * các thành viên được thừa kế được coi là thành viên của loại có nguồn gốc *.Lưu ý rằng chúng tôi rõ ràng * không * cho phép mẫu này trên các thông số loại bị ràng buộc bởi vì sau đó nó thực sự có khả năng khá gây hiểu lầm. Xem http://blogs.msdn.com/b/ericlippert/archive/2007/06/14/calling-static-methods-on-type-parameters-is-illegal-part-one.aspx để biết chi tiết. –

Trả lời

7

Tôi đồng ý rằng đây là sự không hài lòng. Tôi không biết làm thế nào thường ai đó trên Stack Overflow đã gửi mã số:

ASCIIEncoding.ASCII 

vv ... mà, trong khi vô hại về thực hiện được gây hiểu lầm về đọc mã.

Rõ ràng đã quá muộn để xóa "tính năng" này ngay bây giờ, mặc dù tôi đoán nhóm C# có thể giới thiệu chế độ cảnh báo siêu tiết cho vấn đề này và các vấn đề về phong cách khác.

Có thể người kế nhiệm của C# sẽ cải thiện mọi thứ ...

+0

Thực ra, tôi chỉ thấy rằng [một lần] (http://stackoverflow.com/questions/4252426/webclient-unicode-which-utf8) trên SO. – SLaks

+0

StyleCop có thể cố gắng nắm bắt chúng. – SLaks

+3

Giống như @SLaks nói, 'UTF8Encoding.ASCII' thậm chí còn tồi tệ hơn – digEmAll

2

Điều này rất hữu ích trong WinForms.

Trong bất kỳ kiểm soát hoặc hình thức, bạn có thể viết MousePosition, MouseButtons, hoặc ModifierKeys sử dụng static thành viên được thừa kế từ Control.

Nó vẫn còn gây tranh cãi cho dù đó là một quyết định tốt.

+1

Bạn vẫn có thể truy cập vào các thành viên tĩnh "kế thừa" thông qua ngữ cảnh ngầm của việc viết một lớp, nhưng không thể truy cập chúng * khi chỉ định tên kiểu * khác với cái đúng. –

+0

Đúng. Tôi không chắc liệu tôi có thể nghĩ ra bất kỳ cách sử dụng nào cho điều đó không. – SLaks

+0

Tôi đồng ý với Jon, hai điều này phần nào là trực giao. Tuy nhiên, vấn đề hồi âm thầm lặng vẫn còn đó, mặc dù đó là vấn đề nhỏ và khó có thể tạo ra trong WinForms. – Ani

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