2016-03-11 17 views
18

Khi IReadOnlyList<T> được giới thiệu trong .NET 4.5, trong một khoảnh khắc, tôi nghĩ rằng phần còn thiếu của câu đố cuối cùng đã được chèn vào: một cách để truyền một giao diện có thể đọc được chỉ mục thực sự mà trước đây tôi sẽ phải sử dụng giao diện chỉ đọc của riêng mình và tạo các lớp bao bọc xung quanh mọi thứ.Tại sao 'IList <T>' không thừa kế từ 'IReadOnlyList <T> `?

Tôi đã chờ đợi giao diện được đặt bên trong hệ thống phân cấp "tự nhiên", mà lý tưởng sẽ là:

IEnumerable<T> 
.GetEnumerator() 
     -> IReadOnlyCollection<T> : IEnumerable<T> 
     .Count 
      -> IReadOnlyList<T> : IReadOnlyCollection<T> 
      .Item[...] 
        -> IList<T> : IReadOnlyList<T> 
        .Add(...) 
        .Clear() 
        .Contains(...) 
        (etc) 

Nhưng, khi nó quay ra, IList<T> không kế thừa từ IReadOnlyList<T>.

Có lý do nào cho điều này không?

+7

Như bạn đã nói 'IReadonlyList' đã được giới thiệu trong .NET4.5 mà sau này' IList' được thêm vào .Net. – HimBromBeere

+4

Kiểm tra điều này: https://social.msdn.microsoft.com/Forums/vstudio/en-US/b4fb991a-3f5c-4923-93d4-7cd5c004f859/new-interfaces-ireadonlylist-and-ireadonlydictionary?forum=netfxbcl –

+6

'Danh sách <> 'thực hiện' IList <> 'nhưng nó không chỉ đọc, vậy tại sao nó nên thực hiện' IReadOnlyList <> '?. –

Trả lời

23

@ w.b đặt một liên kết đến New interfaces IReadOnlyList and IReadOnlyDictionary trong các ý kiến ​​có chứa một câu trả lời:

Tại sao chúng ta không thay đổi giao diện hiện có để mở rộng giao diện chỉ đọc?

Dường như giả định hợp lý là nó hoạt động vì giao diện chỉ đọc hoàn toàn là tập con của giao diện đọc-ghi. Thật không may, nó không tương thích vì ở cấp siêu dữ liệu mọi phương thức trên mọi giao diện đều có khe riêng của nó (làm cho việc triển khai giao diện rõ ràng hoạt động).


Immo Landwerth | .NET Framework Team (BCL) | http://blogs.msdn.com/b/bclteam/

Để giải thích điều này rõ ràng hơn một chút:

Giả sử rằng một chương trình viết cho NET 4.0 chứa một lớp MyList<T> mà thực hiện IList<T>. Rõ ràng là không thể triển khai IReadOnlyList<T> vì giao diện đó không tồn tại.

Bây giờ giả sử quản trị viên hệ thống cài đặt .NET 4.5 và giả sử rằng .NET 4.5 đã thực hiện IList<T> triển khai IReadOnlyList<T>.

Nếu chương trình sau đó sẽ được tải, thời gian chạy sẽ phát hiện rằng MyList<T> tuyên bố thực hiện IList<T>, nhưng không thực sự triển khai tất cả các phương pháp: nó không thực hiện phương thức của IReadOnlyList<T>. Chương trình sẽ không hoạt động nữa.

Trình biên dịch C# có thể khớp với các phương thức theo tên, nhưng thời gian chạy không thực hiện được điều này. Vì .NET 4.5 được cho là có khả năng tương thích nhị phân ngược, các giao diện không thể được mở rộng để triển khai các giao diện khác, thậm chí nếu các giao diện khác chứa một tập hợp con nghiêm ngặt các phương thức cần thiết.

+2

+1 Và một ví dụ khác dựa trên tham chiếu của trích dẫn để thực hiện rõ ràng. Nếu một lớp đã có một 'int IList .Count ...' implementation và 'IList ' sẽ kế thừa từ 'IReadOnlyList ', Count sẽ thuộc về sau và việc triển khai hiện tại sẽ thất bại, ngay cả khi xây dựng với đúng khuôn khổ. –

+0

@ Me.Name Đó cũng là một ví dụ hay, mặc dù tôi cho rằng có thể giải được một phần mở rộng cho C#. – hvd

+0

+1 Vâng crap, tôi cho rằng nó sẽ là một cái gì đó như thế này. Tôi đoán nó đủ tốt để có 'Danh sách ' và 'T []' thực hiện nó. – Lou

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