Để trả lời phần "tại sao" của câu hỏi là tại sao không List<T>
, Lý do là bằng chứng trong tương lai và tính đơn giản của API.
Chứng minh trong tương lai
List<T>
không được thiết kế để có thể dễ dàng mở rộng bằng cách phân lớp nó; nó được thiết kế để nhanh chóng thực hiện nội bộ. Bạn sẽ nhận thấy các phương thức trên nó không phải là ảo và do đó không thể bị ghi đè và không có móc nối nào trong Add
/ Insert
/ Remove
hoạt động của nó .
Điều này có nghĩa là nếu bạn cần thay đổi hành vi của bộ sưu tập trong tương lai (ví dụ: từ chối các đối tượng null mà mọi người cố gắng thêm hoặc thực hiện công việc bổ sung khi điều này xảy ra như cập nhật trạng thái lớp của bạn) thì bạn cần thay đổi loại của bộ sưu tập bạn quay lại một lớp bạn có thể phân lớp, đây sẽ là một thay đổi giao diện vi phạm (tất nhiên thay đổi ngữ nghĩa của những thứ như không cho phép null cũng có thể là thay đổi giao diện, nhưng những thứ như cập nhật trạng thái lớp bên trong của bạn sẽ không).
Vì vậy, bằng cách trả về một lớp có thể dễ dàng được phân lớp như Collection<T>
hoặc một giao diện như IList<T>
, ICollection<T>
hoặc IEnumerable<T>
bạn có thể thay đổi triển khai nội bộ của mình thành một loại bộ sưu tập khác để đáp ứng nhu cầu của bạn, mà không phá vỡ mã của người tiêu dùng vì vẫn có thể được trả lại như loại họ đang mong đợi.
Đơn giản API
List<T>
chứa rất nhiều hoạt động hữu ích như BinarySearch
, Sort
v.v. Tuy nhiên nếu đây là bộ sưu tập bạn đang trưng bày thì có khả năng bạn sẽ kiểm soát ngữ nghĩa của danh sách chứ không phải người tiêu dùng. Vì vậy, trong khi lớp học của bạn có thể cần các hoạt động này, rất khó có khả năng người tiêu dùng của lớp bạn muốn (hoặc thậm chí nên) gọi chúng.
Như vậy, bằng cách cung cấp lớp bộ sưu tập hoặc giao diện đơn giản hơn, bạn giảm số lượng thành viên mà người dùng API của bạn nhìn thấy và giúp họ sử dụng dễ dàng hơn.