Lập trình C#

Làm việc với Collection và Generic trong C#

Làm việc với Collection và Generic trong C#
Được viết bởi Minh Hoàng

Series lập trình C#, ngôn ngữ lập trình hiện đại và mạnh mẽ.

Trong bài viết này, chúng ta sẽ cùng tìm hiểu về CollectionGeneric trong lập trình hướng đối tượng C#.
Nội dung chính:

  1. Collection
  2. Generic
#1/2. Làm việc với Collection

Collection là một tập hợp các dữ liệu không cùng kiểu, ví dụ khi khai báo ArrayList arrList = new ArrayList() { 1, “5”, 2.5, true };. Collection cung cấp rất nhiều các method giúp lập trình viên thao tác với dữ liệu một cách đơn giản và dễ dàng.

– Một trong những ưu điểm lớn nhất của Collection là khả năng tương tác và thay đổi dữ liệu bên trong nó ngay tại thời điểm chạy (runtime).

Collection thuộc thư viện System.Collections

– Các lớp Collection là các lớp đặc biệt để lưu trữ và thu hồi dữ liệu. Những lớp này cung cấp sự hỗ trợ cho Stack, Queue, List, Hashtable.

– Đa số các lớp Collection trong C# triển khai cùng các Interface.

– Trong C#, các lớp Collection được sử dụng cho nhiều mục đích khác nhau như cấp phát bộ nhớ động cho các phần tử, hay truy cập một danh sách các item dựa trên chỉ mục,…

Các Collection phổ biến:
Tên class Ý nghĩa
ArrayList
Generic Collection:
List<>
Truy cập phần tử (item) theo Chỉ mục. Nó là một sự thay thế cho mảng. Không giống mảng, ArrayList có thể thêm, xóa item thông qua chỉ mục và chính nó có thể tự điều chỉnh size một cách tự động. Ngoài ra, nó cũng cho phép cấp phát bộ nhớ động, thêm, tìm kiếm, sắp xếp,… các item trong một list.
Hashtable
Generic Collection:
Dictionary<>

DictionaryEntry
Generic Collection:
KeyValuePair<>

Truy cập phần tử (item) theo Key. Lớp Hashtable sử dụng một cặp Key-Value để truy cập các item trong collection. Mỗi item trong Hashtable được truy cập bởi Key và sẽ có một Value tương ứng..
SortedList
Generic Collection:
SortedList<>
Truy cập phần tử (item) theo Key, cũng như Chỉ mục để truy các item trong một list. Một SortedList là sự tổ hợp của một mảng và một Hashtable. Nếu truy cập item bằng cách sử dụng chỉ mục thì nó là một ArrayList, còn nếu access bằng key thì nó là một Hashtable. Tập hợp các item LUÔN LUÔN được SẮP XẾP theo giá trị KEY.
Stack Lớp Stack trong C# biểu diễn một tập hợp LIFO (Last In, First Out) của các đối tượng. Nó được sử dụng khi muốn truy cập các item theo dạng LIFO. Khi thêm một item vào danh sách thì được gọi là pushing, còn khi remove một item thì gọi là popping. Stack tức là ngăn xếp, push: thêm item mới vào đỉnh stack, pop: thao tác lấy một phần tử từ đỉnh stack.
Queue Lớp Queue sẽ truy cập các item theo dạng FIFO (First In, First Out). Khi thêm một item vào danh sách thì được gọi là enqueue, còn khi remove một item thì gọi là deque.
BitArray Nó biểu diễn một mảng ở dạng biểu diễn nhị phân bởi sử dụng các giá trị 1 và 0. Nó được sử dụng khi bạn cần lưu giữ các Bit nhưng không biết trước số lượng Bit. Bạn có thể truy cập các item từ BitArray collection bởi sử dụng một chỉ mục là số nguyên, mà bắt đầu từ 0.
#2/2. Làm việc với Generic

Generic được giới thiệu từ C# 2.0. Generic cho phép bạn xác định một class với trình giữ chỗ (placeholders) cho fields, methods, parameters,… Generic thay thế các placeholders này bằng một số loại dữ liệu cụ thể tại thời gian biên dịch (compile time). Có nghĩa là, generic là tính năng cho phép bạn trì hoãn chỉ ra kiểu dữ liệu khi khai báo classes hoặc methods,… cho đến khi chương trình được thực thi.

Generic được định nghĩa bằng cách sử dụng dấu ngoặc nhọn <>. Trong .NET có sẵn trong namespace: System.Collections.Generic

Generic cũng là một kiểu dữ liệu trong C# như int, string, bool,… nhưng nó là một kiểu dữ liệu “tự do”, tùy vào mục đích sử dụng mà nó có thể đại diện cho tất cả các kiểu dữ liệu còn lại.

– Đặc điểm của generic:

  • Giúp tối đa hóa sử dụng lại code (chỉ cần viết 1 hàm có thể tái sử dụng cho nhiều kiểu dữ liệu), an toàn và tăng tốc độ.
  • Có thể dùng generic với: interfaces, classes, methods, events, delegates, structs.
  • Có thể tạo generic class với ràng buộc cho các method trong class.
  • Bạn có thể lấy thông tin của kiểu dữ liệu được sử dụng bởi generic ở thời điểm runtime bằng Reflection.

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

Generic Collections Mô tả
List<T> Chứa các elements của loại được chỉ định. Kích thước sẽ tăng lên tự động khi bạn thêm các elements vào danh sách.
Dictionary<TKey,TValue> Chứa các cặp key-value.
Hashset<T> Chứa các phần tử không trùng lặp.
SortedList<TKey,TValue> Lưu trữ các cặp key và value. Nó tự động thêm các elements theo thứ tự tăng dần, mặc định sắp xếp theo key.
Stack<T> Lưu trữ các giá trị dưới dạng LIFO (Last In First Out). Nó cung cấp phương thức Push() để thêm giá trị và phương thức Pop(), Peek() để truy xuất giá trị.
Queue<T> Lưu trữ các giá trị theo kiểu FIFO (First In First Out). 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.
Ví dụ 1/2:

Sau đây là một generic class đơn giản với một generic field, generic propertygeneric method.

using System;

namespace MinhHoangBlog
{
	class Program
	{
		static void Main(string[] args)
		{
			GenericClass<int> intGenericClass = new GenericClass<int>(86);
			intGenericClass.genericProperty = 2017;
			int intVal = intGenericClass.genericMethod(2019);

			GenericClass<string> strGenericClass = new GenericClass<string>("Welcome to");
			strGenericClass.genericProperty = "Minh Hoàng Blog";
			string strVal = strGenericClass.genericMethod("www.minhhn.com");

			Console.ReadKey();
		}
	}

	class GenericClass<T>
	{
		private T genericField;

		public T genericProperty { get; set; }

		// Constructor
		public GenericClass(T val)
		{
			genericField = val;
		}

		public T genericMethod(T genericParameter)
		{
			T rtn = default(T);

			Console.WriteLine("Field type: {0}, value: {1}", typeof(T).ToString(), genericField);
			Console.WriteLine("Property type: {0}, value: {1}", typeof(T).ToString(), genericProperty);
			Console.WriteLine("Parameter type: {0}, value: {1}", typeof(T).ToString(), genericParameter);

			Console.WriteLine("Return type: {0}", typeof(T).ToString());

			return rtn;
		}
	}
}

・Như bạn có thể thấy trong đoạn mã trên, GenericClass được định nghĩa bằng <T>. <> chỉ ra rằng GenericClass là chung chung và loại dữ liệu cụ thể sẽ được xác định sau, bây giờ tạm thời hãy xem nó là T. Bạn có thể lấy bất kỳ ký tự nào thay vì dùng chữ T.

・Bây giờ, trình biên dịch gán loại dữ liệu dựa trên loại dữ liệu được người gọi truyền qua khi khởi tạo một lớp GenericClass. Ở đây trong hàm main(), chúng ta truyền 2 loại dữ liệu khác nhau là intstring:

Kết quả chương trình

Kết quả chương trình

Ví dụ 2/2:

Sau đây sẽ minh họa code hoán vị sử dụng generic, bạn có thể hoán vị số hoặc chuỗi. Nhờ có generic giúp chúng ta giảm thiểu việc code và tăng tính tái sử dụng.

Xem thêm: Cách truyền tham trị, tham chiếu trong C#.

using System;

namespace MinhHoangBlog
{
	class Program
	{
		static void Main(string[] args)
		{
			int x = 6;
			int y = 8;

			Console.WriteLine("Trước khi hoán vị: x = {0}, y = {1}", x, y);
			HoanVi<int>(ref x, ref y);
			Console.WriteLine("Sau khi hoán vị: x = {0}, y = {1}", x, y);

			string str1 = "Minh Hoàng Blog";
			string str2 = "www.minhhn.com";

			Console.WriteLine("Trước khi hoán vị: str1 = {0}, str2 = {1}", str1, str2);
			HoanVi<string>(ref str1, ref str2);
			Console.WriteLine("Sau khi hoán vị: str1 = {0}, str2 = {1}", str1, str2);

			Console.ReadKey();
		}

		static void HoanVi<T>(ref T a, ref T b)
		{
			T tmp = a;
			a = b;
			b = tmp;
		}
	}
}
Kết quả chương trình

Kết quả chương trình

Cảm ơn bạn đã theo dõi. Đừng ngần ngại hãy cùng thảo luận với chúng tôi!

Giới thiệu

Minh Hoàng

Xin chào, tôi là Hoàng Ngọc Minh, hiện đang làm BrSE, tại công ty Toyota, Nhật Bản. Những gì tôi viết trên blog này là những trải nghiệm thực tế tôi đã đúc rút ra được trong cuộc sống, quá trình học tập và làm việc. Các bài viết được biên tập một cách chi tiết, linh hoạt để giúp người đọc có thể tiếp cận một cách dễ dàng nhất. Hi vọng nó sẽ có ích hoặc mang lại một góc nhìn khác cho bạn[...]

2
Bình luận của bạn

avatar
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
0 Comment authors
Recent comment authors
Mới nhất Cũ nhất Thích nhiều nhất
trackback

[…] niệm IEnumerable thì chắc nhiều bạn biết. Các kiểu collection trong C# như List, ArrayList, Dictionary,… đều implement interface IEnumerable, do đó […]

Làm việc với Collection và Generic trong C#

by Minh Hoàng Time to read: 8 min
2