C # – Generics


Generics cho phép bạn xác định đặc điểm kỹ thuật của kiểu dữ liệu của các phần tử lập trình trong một lớp hoặc một phương thức, cho đến khi nó thực sự được sử dụng trong chương trình. Nói cách khác, generic cho phép bạn viết một lớp hoặc phương thức có thể hoạt động với bất kỳ kiểu dữ liệu nào.

Bạn viết các đặc tả cho lớp hoặc phương thức, với các tham số thay thế cho kiểu dữ liệu. Khi trình biên dịch gặp một phương thức khởi tạo cho lớp hoặc một lệnh gọi hàm cho phương thức, nó sẽ tạo ra mã để xử lý kiểu dữ liệu cụ thể. Một ví dụ đơn giản sẽ giúp hiểu khái niệm –

using System;
using System.Collections.Generic;

namespace GenericApplication {
   public class MyGenericArray<T> {
      private T[] array;
      
      public MyGenericArray(int size) {
         array = new T[size + 1];
      }
      public T getItem(int index) {
         return array[index];
      }
      public void setItem(int index, T value) {
         array[index] = value;
      }
   }
   class Tester {
      static void Main(string[] args) {
         
         //declaring an int array
         MyGenericArray<int> intArray = new MyGenericArray<int>(5);
         
         //setting values
         for (int c = 0; c < 5; c++) {
            intArray.setItem(c, c*5);
         }
         
         //retrieving the values
         for (int c = 0; c < 5; c++) {
            Console.Write(intArray.getItem(c) + " ");
         }
         
         Console.WriteLine();
         
         //declaring a character array
         MyGenericArray<char> charArray = new MyGenericArray<char>(5);
         
         //setting values
         for (int c = 0; c < 5; c++) {
            charArray.setItem(c, (char)(c+97));
         }
         
         //retrieving the values
         for (int c = 0; c< 5; c++) {
            Console.Write(charArray.getItem(c) + " ");
         }
         Console.WriteLine();
         
         Console.ReadKey();
      }
   }
}

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

0 5 10 15 20
a b c d e

Các tính năng của Generics

Generics là một kỹ thuật làm phong phú thêm các chương trình của bạn theo những cách sau:

  • Nó giúp bạn tối đa hóa việc tái sử dụng mã, nhập an toàn và hiệu suất.

  • Bạn có thể tạo các lớp tập hợp chung. Thư viện lớp .NET Framework chứa một số lớp thu thập chung mới trong System.Collections.Generic không gian tên. Bạn có thể sử dụng các lớp tập hợp chung này thay vì các lớp tập hợp trong System.Collections không gian tên.

  • Bạn có thể tạo giao diện, lớp, phương thức, sự kiện và đại biểu chung của riêng mình.

  • Bạn có thể tạo các lớp chung bị ràng buộc để cho phép truy cập vào các phương thức trên các kiểu dữ liệu cụ thể.

  • Bạn có thể nhận được thông tin về các loại được sử dụng trong một loại dữ liệu chung tại thời điểm chạy bằng cách phản ánh.

Phương pháp chung

Trong ví dụ trước, chúng ta đã sử dụng một lớp chung; chúng ta có thể khai báo một phương thức chung với một tham số kiểu. Chương trình sau đây minh họa khái niệm –

using System;
using System.Collections.Generic;

namespace GenericMethodAppl {
   class Program {
      static void Swap<T>(ref T lhs, ref T rhs) {
         T temp;
         temp = lhs;
         lhs = rhs;
         rhs = temp;
      }
      static void Main(string[] args) {
         int a, b;
         char c, d;
         a = 10;
         b = 20;
         c="I";
         d = 'V';
         
         //display values before swap:
         Console.WriteLine("Int values before calling swap:");
         Console.WriteLine("a = {0}, b = {1}", a, b);
         Console.WriteLine("Char values before calling swap:");
         Console.WriteLine("c = {0}, d = {1}", c, d);
         
         //call swap
         Swap<int>(ref a, ref b);
         Swap<char>(ref c, ref d);
         
         //display values after swap:
         Console.WriteLine("Int values after calling swap:");
         Console.WriteLine("a = {0}, b = {1}", a, b);
         Console.WriteLine("Char values after calling swap:");
         Console.WriteLine("c = {0}, d = {1}", c, d);
         
         Console.ReadKey();
      }
   }
}

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

Int values before calling swap:
a = 10, b = 20
Char values before calling swap:
c = I, d = V
Int values after calling swap:
a = 20, b = 10
Char values after calling swap:
c = V, d = I

Đại biểu Chung

Bạn có thể xác định một đại biểu chung với các tham số kiểu. Ví dụ –

delegate T NumberChanger<T>(T n);

Ví dụ sau cho thấy việc sử dụng đại biểu này:

using System;
using System.Collections.Generic;

delegate T NumberChanger<T>(T n);
namespace GenericDelegateAppl {
   class TestDelegate {
      static int num = 10;
      
      public static int AddNum(int p) {
         num += p;
         return num;
      }
      public static int MultNum(int q) {
         num *= q;
         return num;
      }
      public static int getNum() {
         return num;
      }
      static void Main(string[] args) {
         //create delegate instances
         NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
         NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
         
         //calling the methods using the delegate objects
         nc1(25);
         Console.WriteLine("Value of Num: {0}", getNum());
         
         nc2(5);
         Console.WriteLine("Value of Num: {0}", getNum());
         Console.ReadKey();
      }
   }
}

Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:

Value of Num: 35
Value of Num: 175