Computer >> Máy Tính >  >> Lập trình >> C#

Giải thích cách hoạt động của generic trong C #

Generics đã được thêm vào phiên bản 2.0 của C # và là một trong những khái niệm quan trọng nhất trong ngôn ngữ này. Chúng cho phép bạn viết mã hiệu suất cao, có thể tái sử dụng và an toàn về kiểu chữ tại thời điểm biên dịch. Sử dụng generic, bạn có thể sử dụng một loại mã của mình mà không cần biết trước về nó.

Generics được sử dụng ở nhiều nơi trong .NET, bao gồm bộ sưu tập, đại biểu và mã không đồng bộ. Với generic, bạn không cần biết trước kích thước của bộ sưu tập và bạn có thể sử dụng generic với bất kỳ loại phần tử nào, ngay cả các loại dữ liệu tùy chỉnh dành riêng cho mã của bạn. C # cung cấp hỗ trợ cho cả kiểu chung (lớp, giao diện, v.v.) và phương thức chung.

Trong generics, bạn có tham số kiểu và đối số kiểu. Điều này tương tự như một phương thức có các tham số và bạn truyền các đối số cho phương thức.

Loại chung

Cú pháp để khai báo một kiểu chung bao gồm các tham số kiểu trong dấu ngoặc nhọn sau tên của kiểu. Ví dụ:Bộ định vị là một lớp chung trong ví dụ dưới đây.

public class Locator<T>
{

}

Để tạo một phiên bản của Locator , bạn sử dụng từ khóa mới, theo sau là tên của lớp. Tuy nhiên, thay vì T, bạn chỉ định kiểu thực mà bạn muốn chuyển làm đối số. Ví dụ sau chuyển kiểu chuỗi làm đối số.

var stringLocator = new Locator<string>();

Bạn có thể sử dụng tham số kiểu (T) trên các phương thức của lớp, như được hiển thị trong ví dụ bên dưới.

public class Locator<T>{
   public IList<T> Items { get; set; }

      public T Locate(int index){
      return Items[index];
   }
}
var stringLocator = new Locator<string>();
string item = stringLocator.Locate(2);

Một lợi ích bổ sung của thuốc chung là IntelliSense được cung cấp bởi trình soạn thảo. Khi bạn nhập stringLocator.Locate (4) vào Visual Studio hoặc VS Code và di chuột qua tên phương thức; nó sẽ cho bạn thấy rằng nó trả về một chuỗi thay vì T. Nếu bạn cố gắng gán kết quả cho bất kỳ kiểu nào khác ngoài chuỗi, trình biên dịch sẽ phát sinh lỗi. Ví dụ,

// Error: Cannot implicitly convert type 'string' to 'int' [c-sharp]csharp(CS0029)
int item = stringLocator.Locate(2);

Kiểu chung có thể sử dụng tham số kiểu làm đối số kiểu khi kế thừa từ kiểu cơ sở chung hoặc giao diện chung. Kiểu LinkedList chung thực hiện giao diện IEnumerable chung, cùng với các giao diện khác.

public class LinkedList<T> : IEnumerable<T>

Phương pháp Chung

Phương thức chung chỉ đơn giản là một phương thức khai báo một tham số kiểu mà bạn có thể sử dụng bên trong phương thức và dưới dạng các tham số và kiểu trả về. Trong ví dụ dưới đây, Swap là một phương thức chung nhận hai tham số kiểu T và trả về một thể hiện của T.

public class Swapper{
   public T Swap<T>(T first, T second){
      T temp = first;
      first = second;
      second = temp;
      return temp;
   }
}

Giống như các kiểu chung, khi bạn gọi một phương thức chung, nó sẽ trả về một biến được định kiểu mạnh.

var swapper = new Swapper();
int result = swapper.Swap<int>(5, 3);

Có thể có nhiều tham số chung. Lớp Từ điển trong không gian tên System.Collections.Generic có hai tham số kiểu, cho khóa và giá trị.

public class Dictionary<TKey, TValue>

Cuối cùng, điều quan trọng là phải biết những gì có thể là chung chung. Đối với các loại, ngoại trừ enum, mọi thứ đều có thể chung chung. Điều đó bao gồm -

  • lớp học
  • cấu trúc
  • giao diện
  • đại biểu

Đối với các thành viên kiểu, chỉ các phương thức và kiểu lồng nhau mới có thể là chung. Các thành viên sau không thể là chung -

  • Các trường
  • Thuộc tính
  • Người lập chỉ mục
  • Trình tạo
  • Sự kiện
  • Người hoàn thiện

Ví dụ

using System;
using System.Collections.Generic;
class Program{
   static void Main(){
      var stringLocator = new Locator<string>(){
         Items = new string[] { "JavaScript", "CSharp", "Golang" }
      };
      string item = stringLocator.Locate(1);
      Console.WriteLine(item); // CSharp
      var swapper = new Swapper();
      int a = 5, b = 3;
      int result = swapper.Swap<int>(ref a, ref b);
      Console.WriteLine($"a = {a}, b = {b}");
   }
}
public class Locator<T>{
   public IList<T> Items { get; set; }
   public T Locate(int index){
      return Items[index];
   }
}
public class Swapper{
   public T Swap<T>(ref T first, ref T second){
      T temp = first;
      first = second;
      second = temp;
      return temp;
   }
}

Đầu ra

CSharp
a = 3, b = 5