2010-08-27 34 views
12

Bây giờ, hãy tìm nó một cách ngẫu nhiên, Thêm (T) được xác định trong ICollection<T>, thay vì IEnumerable<T>. Và các phương thức mở rộng trong Enumerable.cs không chứa Add (T), mà tôi nghĩ là rất kỳ lạ. Vì một đối tượng được liệt kê, nó phải "trông giống như" một tập hợp các mục. bất cứ ai đó có thể trả lời tôi tại sao?Tại sao IEnumerable <T> không triển khai Add (T)?

+0

Đã 'IEnumerable ' cần thiết 'Add' được thực hiện, sẽ có nhiều hơn nữa các câu hỏi cách khác xung quanh: * Tại sao 'IEnumerable 'có' Add' *. Theo cách của nó, rất hữu ích :) – nawfal

Trả lời

45

An IEnumerable<T> chỉ là một chuỗi các phần tử; xem nó như một con trỏ chỉ về phía trước. Bởi vì rất nhiều các chuỗi đó tạo ra các giá trị, các luồng dữ liệu hoặc các bộ bản ghi từ một cơ sở dữ liệu, nó không có ý nghĩa với các mục Add đối với chúng.

+9

+1 để sử dụng từ * chuỗi *, vì IEnumerable chính xác là như vậy, và không phải là một loại bộ sưu tập nào đó. – OregonGhost

+5

Các downvoters có thể giải thích lý do tại sao họ downvoted? – Steven

11

IEnumerable dùng để đọc, không phải để viết.

2

Như tên gọi của nó, bạn có thể liệt kê (vòng lặp) trên một IEnumerable, và đó là về nó. Khi bạn muốn có thể Thêm một cái gì đó vào nó, nó sẽ không chỉ là một enumerable nữa, vì nó có tính năng bổ sung.

Ví dụ, một mảng là một IEnumerable, nhưng một mảng có độ dài cố định, vì vậy bạn không thể thêm các mục mới vào nó.

IEnumerable chỉ là 'cơ sở' cho tất cả các loại bộ sưu tập (ngay cả các bộ sưu tập chỉ đọc - rõ ràng là không có phương thức Add()). Bạn sẽ thêm nhiều chức năng hơn vào giao diện cơ bản như vậy, nó càng cụ thể hơn.

10

Đếm là chính xác - thứ mà bạn có thể liệt kê và khám phá tất cả các mục. Nó không ngụ ý rằng bạn có thể thêm vào nó.

Có khả năng liệt kê là phổ quát đối với nhiều loại đối tượng. Ví dụ, nó được chia sẻ bởi mảng và bộ sưu tập. Nhưng bạn không thể 'thêm' vào một mảng mà không làm rối tung với cấu trúc của nó - trong khi Bộ sưu tập được xây dựng đặc biệt để thêm vào và bị loại bỏ.

Về mặt kỹ thuật, bạn có thể 'thêm' vào một số, tuy nhiên - bằng cách sử dụng Concat<> - tuy nhiên tất cả điều này là tạo ra một điều tra liệt kê từ một đếm sang kế tiếp - cho ảo giác của một tập hợp duy nhất.

+0

+1 để đề xuất phương án thay thế, Concat. – Emile

2

Tên nói lên tất cả. IEnumerable chỉ để liệt kê các mục. ICollection là bộ sưu tập thực sự của các mục và do đó hỗ trợ phương thức Add.

3

Mỗi ICollection phải là IEnumerable (Tôi nghĩ, và nhóm .NET Framework có vẻ đồng ý với tôi ;-)), nhưng cách khác xung quanh không phải lúc nào cũng hợp lý. Có một hệ thống phân cấp của "bộ sưu tập như các đối tượng" trong thế giới này, và giả định của bạn rằng một enumerable sẽ là một bộ sưu tập bạn có thể thêm các mục để không giữ đúng trong hệ thống phân cấp đó.

Ví dụ: danh sách tên màu chính sẽ là IEnumerable trả lại "Red", "Blue""Green". Nó sẽ làm cho không có ý nghĩa logic ở tất cả để có thể làm một primaryColors.Add("Bright Purple") trên một "bộ sưu tập" điền như thế này:

...whatever... 
{ 
    ... 
    var primaryColors = EnumeratePrimaryColors(); 
    ... 
} 

private static IEnumerable<string> EnumeratePrimaryColors() { 
    yield return "Red"; 
    yield return "Blue"; 
    yield return "Green"; 
} 
+0

'ICollection' kế thừa từ 'IEnumerable' và' ICollection 'kế thừa từ' IEnumerable ' (được kế thừa từ 'IEnumerable'). Nói cách khác, bạn là đúng: Mỗi 'ICollection' là một 'IEnumerable'. – Steven

+0

@Steven: Tôi biết ... – peSHIr

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