2009-09-08 34 views
6

Giao diện IList yêu cầu phương thức Thêm. Các mảng thực hiện hàm này nhưng nó đơn giản ném một NotImplementedException. Điều này có vẻ như thiết kế rất xấu với tôi.Tại sao mảng hỗ trợ IList?

Các nhà thiết kế nghĩ gì khi họ làm điều này?

Trả lời

7

Quyền hạn có thể chỉ đọc được - nếu nghi ngờ người gọi có thể kiểm tra thuộc tính IsFixedSize trước khi cố gắng thêm hoặc xóa phần tử hoặc thuộc tính IsReadOnly trước khi cố sửa đổi phần tử.

Mảng là một IList có kích thước cố định.

Có thể thuận tiện để có thể xử lý một mảng dưới dạng danh sách. Một ví dụ là chế nhạo một phương thức truy cập dữ liệu trả về một IList - nó có thể được mô phỏng để chỉ đơn giản trả về một mảng cast như một IList.

+1

Đó thực sự là thuộc tính 'IsFixedSize' mà bạn cần kiểm tra. 'IsReadOnly' sẽ là' false' cho mảng bởi vì các phần tử hiện có có thể được sửa đổi. 'IsFixedSize' sẽ là' true' vì không thể thêm hoặc xóa các phần tử. – LukeH

+0

Chỉ để làm rõ vấn đề với cố định và chỉ đọc: http://blogs.msdn.com/ericlippert/archive/2009/08/27/what-s-the-difference-between-fixed-and-fixed.aspx – Oliver

+1

@Oliver: Tôi là một fan hâm mộ lớn của blog của Eric Lippert, nhưng bài viết đó hoàn toàn không liên quan gì tới thuộc tính 'IsFixedSize' hoặc' IsReadOnly'. – LukeH

0

Bởi vì nó là phổ biến cho các đối tượng khác nhau có khả năng khác nhau, một số giao diện bao gồm các thành viên sẽ được thực hiện bởi một số nhưng không phải tất cả triển khai. Nếu một số, nhưng không phải tất cả, việc triển khai giao diện giả định IVehicle sẽ có thể đính kèm đoạn giới thiệu, một mẫu điển hình là xác định chức năng của AttachTrailer là "Cố gắng đính kèm đoạn giới thiệu, nếu CanAttachTrailer là đúng hoặc ném NotSupportedException" . Tất cả các triển khai của IVehicle sẽ có thể tuân thủ đặc điểm kỹ thuật ở trên, cho dù chúng có thể xử lý các đoạn giới thiệu hay không.

Lợi thế của phương pháp này là có thể triển khai giao diện để cung cấp nhiều kết hợp tính năng khác nhau mà không phải xác định các loại khác nhau cho các kết hợp khác nhau. Một ưu điểm khác của phương pháp này là có thể cho một phương thức Foo nhận một đối tượng bao gồm các khả năng mà Foo không cần, để chuyển đối tượng đó theo phương thức Bar, cần những khả năng đó mà không yêu cầu bất kỳ kiểu nào ở bất kỳ đâu và nếu không có Foo, hãy biết những khả năng nào Bar sẽ cần. Tuy nhiên, một ưu điểm khác là điều này giúp dễ dàng viết mã mà không cần một số khả năng nhất định, nhưng có thể tận dụng chúng khi chúng tồn tại.

Tuy nhiên, có một số nhược điểm đối với phương pháp này. Vẫn chưa có cách nào cho một giao diện để chỉ định việc triển khai mặc định cho bất kỳ thuộc tính hoặc phương thức nào. Do đó, ngay cả các triển khai IVehicle không thể đính kèm đoạn giới thiệu phim sẽ cần bao gồm mã để trả lại false cho thuộc tính CanAttachTrailer và ném ngoại lệ trong phương thức AttachTrailer của chúng. Hơn nữa, vì giao diện không yêu cầu nhiều phương thức của nó được triển khai, nên không có cách nào một trình biên dịch có thể biết để từ chối khi cố gọi tới một hàm yêu cầu khả năng với một đối tượng thuộc kiểu không thể cung cấp.

Khi thiết kế IList<T>, Microsoft dường như nghĩ rằng ưu điểm của phương pháp "giao diện tùy chọn khả năng" vượt quá những bất lợi. Thật vậy, nếu .net cung cấp phương tiện cho các lớp triển khai giao diện để trì hoãn việc triển khai mặc định của các thành viên mà họ không muốn cung cấp, sẽ có ít lý do không bao gồm nhiều khả năng tùy chọn trong các giao diện cấp cơ sở; để cho phép thực thi biên dịch các khả năng cần thiết, người ta có thể có một số giao diện xuất phát từ một cơ sở bao gồm tất cả các thành viên cần thiết, và xác định rằng các lớp thực hiện các giao diện sau phải thực hiện một số thành viên theo cách thực sự hữu ích. Ví dụ: Microsoft có thể đã xác định IResizableList<T> để kế thừa IList<T> mà không thêm bất kỳ thành viên nào, nhưng với kỳ vọng rằng IList<T> triển khai cho phép thay đổi kích thước sẽ triển khai giao diện thứ hai, trong khi những người không cho phép thay đổi kích thước sẽ không triển khai.Họ đã làm điều đó, mã cần thiết để có thể thay đổi kích thước danh sách có thể yêu cầu IResizableList<T> (trong trường hợp nó sẽ không chấp nhận một mảng), trong khi mã không cần phải thay đổi kích thước danh sách có thể yêu cầu IList<T>). Thật không may, Microsoft đã không làm bất cứ điều gì như vậy, do đó, nó không thể cho mã để yêu cầu một danh sách thay đổi kích cỡ tại thời gian biên dịch - tất cả nó có thể làm là squawk nếu một danh sách thông qua báo cáo chính nó như là kích thước cố định.

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