Collection trong C#

Chúng ta đã tìm hiểu về một mảng trong C# ở phần trước. C# cũng có các lớp chuyên biệt chứa nhiều giá trị hoặc đối tượng trong một chuỗi cụ thể, được gọi là collection. Nếu chưa đọc bài viết về mảng trong C# bạn có thể xem ở link dưới đây:

Mảng trong C# | Comdy
Mảng trong C# là gì? Làm sao để tạo và sử dụng mảng trong C#. Bài viết này sẽ hướng dẫn chi tiết cho bạn.

Có hai loại collection được tính hợp sẵn trong C#: non-generic collection (danh sách không định kiểu mạnh)generic collection (danh sách định kiểu mạnh).

Non-generic collection trong C#

Không gian tên System.Collections có các interface và các lớp cho các non-generic collection. Sơ đồ sau minh họa hệ thống phân cấp của các giao diện và các lớp cho non-generic collection.

Non-generic collection trong C#

Như bạn có thể thấy trong sơ đồ trên, IEnumerator, IEnumerable và ICollection là các interface cấp cao nhất cho tất cả các collection trong C#.

IEnumerator: interface IEnumerator hỗ trợ một phương pháp duyệt danh sách đơn giản trên một non-generic collection. Nó bao gồm các phương thức và thuộc tính có thể được thực hiện để hỗ trợ phương pháp duyệt bằng vòng lặp foreach.

IEnumerable: interface IEnumerable gồm phương thức GetEnumerator() trả về một đối tượng của IEnumerator.

Vì vậy, tất cả các lớp collection tích hợp sẵn và các lớp collection do người dùng tự định nghĩa phải triển khai thực hiện các interfaceIEnumerator và IEnumerable để có thể duyệt danh sách bằng cách sử dụng vòng lặp foreach.

ICollection: interface ICollection là interface cơ sở cho tất cả các collection xác định kích thước, liệt kê và phương thức đồng bộ hóa cho tất cả các non-generic collection. Queue và Stack triển khai thực hiện inferface ICollection.

IList: interface IList gồm các thuộc tính và phương thức để thêm, chèn, xóa các phần tử trong collection và cả phần tử riêng lẻ có thể được truy cập theo chỉ mục. ArrayList và BitArray triển khai thực hiện interface IList.

IDictionary: interface IDictionary đại diện cho một non-generic collection có các cặp khóa / giá trị. Hashtable và SortedList triển khai thực hiện interface IDictionary do đó chúng có thể lưu trữ các cặp khóa / giá trị.

Như bạn có thể thấy từ sơ đồ, các non-generic collection như: ArrayList, BitArray, Hashtable, SortedList, Queue và Stack triển khai thực hiện các interface khác nhau do đó chúng được sử dụng cho các mục đích khác nhau.

Lớp Miêu tả và Cách sử dụng
ArrayList ArrayList lưu trữ các đối tượng thuộc bất kỳ kiểu dữ liệu nào như một mảng. Tuy nhiên, không cần chỉ định kích thước của ArrayList như với một mảng thông thường vì nó tự động thay đổi kích thước.
Hashtable Hashtable lưu trữ cặp khóa và giá trị. Nó lấy các giá trị bằng cách so sánh giá trị băm của các khóa.
SortedList SortedList lưu trữ các cặp khóa và giá trị. Nó tự động sắp xếp các phần tử theo thứ tự tăng dần của khóa theo mặc định.
Stack Stack lưu trữ các giá trị theo kiểu LIFO (Last In First Out - vào sau ra trước). Nó cung cấp phương thức Push() để thêm giá trị và phương thức Pop() và Peek() để truy xuất giá trị từ collection.
Queue Queue lưu trữ các giá trị theo kiểu FIFO (First In First Out - vào trước ra trước). Nó giữ thứ tự mà các giá trị đã được thêm vào. Nó cung cấp một phương thức Enqueue() để thêm các giá trị và phương thức Dequeue() để lấy các giá trị từ collection.
BitArray BitArray quản lý một mảng nhỏ các giá trị bit, được biểu diễn dưới dạng Boolean, trong đó true chỉ ra rằng bit đang bật (1) và false chỉ ra bit bị tắt (0).

Generic Collection trong C#

Chúng ta đã tìm hiểu về non-generic collection trong phần trước. Ví dụ: ArrayList, BitArray, SortedList, Queue , Stack và Hashtable.

Hạn chế của non-generic collection là trong khi truy xuất các phần tử, bạn cần ép kiểu dữ liệu phù hợp, nếu không chương trình sẽ đưa ra một ngoại lệ lúc thực thi (runtime). Nó cũng ảnh hưởng đến hiệu suất của hệ thống, vì phải thực hiện boxing và unboxing.

Để khắc phục vấn đề này, C# cung cấp các lớp generic collection trong namespace System.Collections.Generic .

Sau đây là các generic collection được sử dụng rộng rãi:

Lớp Mô tả
List<T> List<T> chứa các thành phần của kiểu dữ liệu được chỉ định. Nó tự động thay đổi kích thước khi bạn thêm các phần tử trong đó.
Dictionary<TKey,TValue> Dictionary<TKey,TValue> chứa các cặp khóa và giá trị.
SortedList<TKey,TValue> SortedList<TKey,TValue> lưu trữ các cặp khóa và giá trị. Nó tự động thêm các phần tử theo thứ tự tăng dần của khóa.
Hashset<T> Hashset<T> chứa các phần tử không trùng lặp. Nó loại bỏ các yếu tố trùng lặp.
Queue<T> Queue<T> lưu trữ các giá trị theo kiểu FIFO (First In First Out - vào trước ra trước). Nó giữ thứ tự mà các giá trị đã được thêm vào. Nó cung cấp một phương thức Enqueue() để thêm các giá trị và phương thức Dequeue() để lấy các giá trị từ collection.
Stack<T> Stack<T> lưu trữ các giá trị dưới dạng LIFO (Last In First Out - Lần vào trước ra trước). Nó cung cấp phương thức Push() để thêm giá trị và phương thức Pop() và Peek() để truy xuất giá trị từ collection.

Một generic collection nhận được tất cả lợi ích của generic trong C#. Nó không cần phải thực hiện boxing  và unboxing trong khi lưu trữ hoặc lấy các phần tử trong collection. Điều này giúp cái thiện hiệu suất của chương trình.

Chúng ta sẽ tìm hiểu từng loại non-generic collection và generic collection cụ thể trong các bài viết theo. Đầu tiên là ArrayList trong C#:

ArrayList trong C# | Comdy
ArrayList trong C# là gì? Cách sử dụng các phương thức phổ biến của ArrayList trong C#.


Bài viết liên quan:

Hướng dẫn này sẽ giúp bạn tìm hiểu về đọc ghi file (File I/O) trong C# và sử dụng các lớp tiện ích để đọc ghi file.

Reflection trong C#

  • 6 min read

Reflection trong C# là gì? Ứng dụng của Reflection trong C#. Cách khai báo và sử dụng Reflection trong C#.

Attribute trong C#

  • 7 min read

Attribute trong C# là gì? Có những loại attribute nào trong C#? Làm sao để sử dụng attribute trong C#.