2010-04-30 33 views
22

Jon's Brain TeasersPhương pháp quá tải và Brain Teasers Jon Skeet

đây Hãy Spoilers ...

Tôi nhìn vào answer vị trí số 1, và tôi phải thừa nhận tôi không bao giờ biết điều này là trường hợp ở độ phân giải quá tải. Nhưng tại sao trường hợp này. Trong tâm trí nhỏ bé của tôi Derived.Foo(int) có vẻ giống như các tuyến đường hợp lý để đi xuống.

Logic đằng sau quyết định thiết kế này là gì?

THỜI GIAN THỜI GIAN!

Hành vi này có phải là kết quả của đặc tả C#, việc triển khai CLR hay Trình biên dịch không?

+0

Đó chắc chắn là hành vi kỳ lạ! Họ có thể thiết kế vào một buổi chiều thứ sáu sau khi uống quá nhiều bia vào giờ ăn trưa. – Etienne

+0

Hoặc sau hàng giờ cân nhắc về hành vi tổng thể tốt nhất sẽ là gì;) – Skurmedel

+0

Tôi đoán bạn đã thấy cùng một điều tôi đã làm vì chúng tôi vừa tranh luận câu trả lời cho cùng một câu hỏi! – NibblyPig

Trả lời

14

Hành vi này có chủ ý và được thiết kế cẩn thận. Lý do là vì sự lựa chọn này làm giảm tác động của một dạng của lớp cơ sở giòn.

Đọc bài viết của tôi về chủ đề này để biết thêm chi tiết.

http://blogs.msdn.com/ericlippert/archive/2007/09/04/future-breaking-changes-part-three.aspx

+0

Tôi biết sẽ có một lý do vững chắc ở đó đâu đó! Vì vậy, (đối với Thời gian thưởng!) Đây có phải là đặc điểm kỹ thuật của C# hoặc CLR không? – gingerbreadboy

+3

@runrunraygun: CLR không có thuật toán phân giải quá tải; quá tải độ phân giải là một khái niệm ngôn ngữ. CLR IL chỉ có các hướng dẫn gọi bất kỳ tham chiếu phương thức nào là ở một vị trí cụ thể. Vì vậy, điều này không thể có thể là một đặc điểm kỹ thuật CLR. Hành vi này được xác định trong phần đặc tả C# 7.6.5.1, điểm bắt đầu "Tập hợp các phương thức ứng cử viên được giảm xuống để chỉ chứa các phương thức từ các kiểu dẫn xuất nhất ..." –

-3

lý do là: hiệu suất. gọi phương thức ảo mất nhiều thời gian hơn một chút. gọi một đại biểu trên một phương pháp ảo mất nhiều thời gian hơn và vân vân ....

see: The cost of method calls

+0

Thật sao? Trong khi thông tin về chi phí cuộc gọi trong rất thú vị và không có nghi ngờ sẽ có ảnh hưởng đến một số quyết định, tôi không chắc chắn tôi có thể nhìn thấy một liên kết trực tiếp giữa hai vấn đề. Có, họ đã chọn không ảo làm mặc định không được xác định vì lý do hiệu suất cuộc gọi phương pháp, điều này thực sự quyết định độ phân giải quá tải đến mức làm cho họ lựa chọn những gì có vẻ như tôi và một số người khác "không trực quan"? Tôi vẫn không thuyết phục rằng đây là lý do xác định, nhưng biết ơn vì một câu trả lời thú vị không ít hơn. T – gingerbreadboy

+8

Điều này hoàn toàn không phải là lý do. –

1

Dưới đây là một lời giải thích có thể:

Khi trình biên dịch liên kết các cuộc gọi phương pháp, là người đầu tiên đặt nó trông trong lớp thấp nhất trong chuỗi thừa kế (trong trường hợp này là lớp Derived). Đó là phương pháp thể hiện được kiểm tra và khớp. Phương thức ghi đè Foo không phải là phương thức thể hiện của Derived, nó là phương thức thể hiện của lớp Base.

Lý do tại sao có thể là hiệu suất, như Jack30lena đã đề xuất, nhưng cũng có thể là cách trình biên dịch diễn giải ý định của người lập trình. Đó là một giả định an toàn rằng hành vi mã dự định của nhà phát triển nằm trong mã ở dưới cùng của chuỗi thừa kế.

+0

Đây là điểm tương tác, xem THỜI GIAN THỜI GIAN! :) – gingerbreadboy

+0

Bởi "thấp nhất" bạn có nghĩa là điều đó là xa nhất từ ​​lớp cơ sở? Thông thường tôi sẽ mô tả điều xa nhất từ ​​căn cứ của một thứ như là thứ "cao nhất". (Sau đó, một lần nữa, gốc của một cây là nút cao nhất trong cây, và điều đó không có ý nghĩa gì cả ...) Điều đó nói rằng, phân tích của bạn là chính xác; nhà phát triển của lớp dẫn xuất biết nhiều hơn nhà phát triển của lớp cơ sở, vì vậy các phương thức của họ được ưu tiên. –

+0

Tôi đã suy nghĩ về thuật ngữ cây. Điều thực sự thú vị là tại sao kiểu ẩn này không dẫn đến ít nhất một cảnh báo. Về cơ bản, bất kỳ phương thức cá thể nào có tham số tổng quát hơn sẽ ẩn hiệu quả ghi đè cụ thể hơn. Tôi biết mã này không hoàn toàn không thể truy cập được (mỗi Foxfire), nhưng nó vẫn ẩn. Có vẻ như nó sẽ tạo ra một cảnh báo. Ngoài ra, cảm ơn bạn đã xác minh câu trả lời của tôi, bài viết của bạn hữu ích. – Audie

-1

Lý do là vì nó không rõ ràng. Trình biên dịch chỉ cần quyết định một. Và ai đó nghĩ rằng người ít gián tiếp sẽ tốt hơn (hiệu suất có thể là một lý do). Nếu nhà phát triển vừa viết:

((Base)d).Foo (i); 

rõ ràng và cho bạn kết quả mong đợi.

1

Đó là kết quả của trình biên dịch, chúng tôi đã kiểm tra mã IL.

+1

Có, nhưng nó giống như vậy vì đặc điểm kỹ thuật. – configurator

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