2011-01-22 30 views
9

thể trùng lặp:
count vs length vs size in a collectionTại sao mảng C# không có thuộc tính Đếm?

Thật lạ:

C# mảng như sự ủng hộ

double[] test = new double[1]; 

sau tài sản dài để có được kích thước của mảng. Nhưng các mảng cũng triển khai giao diện IList:

IList<double> list = test; 

Tuy nhiên, giao diện IList cũng cung cấp thuộc tính Đếm. Làm thế nào đến mảng ("thử nghiệm" trong trường hợp này) không?

Chỉnh sửa: Cảm ơn tất cả các bạn đã chỉ ra rằng trên thực tế giao diện ICollection (không phải IList) cung cấp thuộc tính Đếm và điều này là do thực hiện rõ ràng giao diện.

+2

... vs ** Dung lượng ** so với ** ItemCount ** (như 'ColumnCount' trong' ListView' so với 'Columns.Count') vs ** NumItems ** (' NumIndices' in 'EnvDTE ') vs ** CountOfItems ** (' CountOfLines' trong 'EnvDTE') vs etc ... Tôi chỉ * yêu * sự thống nhất trong các khuôn khổ của MS. :) – Mehrdad

Trả lời

14

Đơn giản, họ đã chọn để gọi nó là Length, và thực hiện Count qua thực hiện giao diện rõ ràng -something thích:

int ICollection.Count { get { return Length; } } 
+2

+1 từ tôi, nhưng tôi đoán có lẽ họ đang tìm kiếm câu trả lời cho phần "tại sao"? – Mehrdad

+1

@mehrdad - Tôi ước tôi có thông số chú thích của mình về tôi: ( –

+1

Cảm ơn bạn đã chỉ cho tôi triển khai giao diện rõ ràng - không có ý tưởng rằng những thứ như vậy tồn tại ;-) – Chris

7

Đó là một lựa chọn thiết kế về Đặt tên, không phải ngữ nghĩa.

Mảng có thuộc tính Độ dài cũng như Chuỗi.

Độ dài tín hiệu không thay đổi: Bạn không thể Thêm hoặc Xóa khỏi mảng.

Danh sách và các vùng chứa khác có số Đếm thuộc tính thường có thể thay đổi.

Ồ, và nếu bạn gọi list.Append(1.1); bạn sẽ nhận được một ngoại lệ không được hỗ trợ.

+10

Độ dài không có nghĩa là tín hiệu không thay đổi; 'MemoryStream' (thực sự, rất nhiều dòng triển khai),' StringBuilder', v.v. –

+0

@Marc: Tôi không ngụ ý ám chỉ một quy tắc rất nghiêm ngặt. Các luồng là một miền khác và tôi nghĩ StringBuilder.Length là một sự nhượng bộ cho Chuỗi. Tôi vẫn nghĩ nó chứa đựng một cách lỏng lẻo. –

4

loại kế thừa từ Arrayobtain implementations of IList<T> at run-time (cách này là có thể, đừng hỏi tôi):

Trong phiên bản .NET Framework 2.0, lớp Array thực hiện các System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, và System.Collections.Generic.IEnumerable<T> giao diện chung. Việc triển khai được cung cấp cho các mảng tại thời gian chạy và do đó không phải là hiển thị đối với công cụ xây dựng tài liệu . Kết quả là, các generic giao diện không xuất hiện trong các cú pháp khai cho lớp Array , và không có tài liệu tham khảo chủ đề cho các thành viên giao diện mà là truy cập chỉ bằng cách đúc một mảng để kiểu giao diện chung (rõ ràng triển khai giao diện).Điều quan trọng cần lưu ý khi bạn bỏ một mảng đến một trong các giao diện này là các thành viên thêm, chèn hoặc xóa các phần tử ném NotSupportedException.

Trong thực tế việc thực hiện IList<T> hoạt động như một explicit implementation, như Marc explained trong câu trả lời của mình. Đây là lý do tại sao bạn có thể truy cập một số thành viên nhất định của IList<T> từ kết quả của một diễn viên nhưng không phải từ một biến được nhập là T[] cụ thể.

+0

Dòng cuối cùng đó là bản chất đã có trong câu hỏi. –

+0

@Henk: Bạn nói đúng; Tôi có nghĩa là để làm nổi bật phần "thực hiện rõ ràng"; bao gồm cả ví dụ mã là thừa và chỉ bị phân tâm từ điểm đó. Tôi đã gỡ bỏ nó. –

3

Thuộc tính Count được ẩn bằng cách sử dụng kiểu khai giao diện rõ ràng, ví dụ như thế này trong một định nghĩa lớp:

int IList.Count { 
    get { 
     // ...etc... 
    } 
} 

Bạn có thể truy cập vào các phương pháp và các thuộc tính ẩn như thế này sử dụng một loại diễn viên, ví dụ

((IList<double>) myArray).Count 
+4

IList không thực sự xác định Đếm; ICollection thực hiện –

+0

@Marc: Cách mà giao diện kế thừa làm cho việc đó thay đổi. –

+0

@Henk - Tôi cần kiểm tra, nhưng nó có * biên dịch * nếu bạn làm sai? Tôi không nghĩ vậy ... –

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