Generics ถูกเพิ่มในเวอร์ชัน 2.0 ของ C# และเป็นหนึ่งในแนวคิดที่สำคัญที่สุดในภาษา สิ่งเหล่านี้ทำให้คุณสามารถเขียนโค้ดที่นำกลับมาใช้ใหม่ได้ ประสิทธิภาพสูง ซึ่งปลอดภัยต่อการพิมพ์ในขณะที่คอมไพล์ เมื่อใช้ชื่อสามัญ คุณจะใช้ประเภทในโค้ดได้โดยไม่ต้องทราบล่วงหน้า
Generics ถูกใช้ในหลายที่ใน .NET รวมถึงคอลเล็กชัน ผู้รับมอบสิทธิ์ และโค้ดแบบอะซิงโครนัส คุณไม่จำเป็นต้องทราบขนาดของคอลเล็กชันล่วงหน้า และคุณสามารถใช้ข้อมูลทั่วไปกับองค์ประกอบประเภทใดก็ได้ แม้แต่ประเภทข้อมูลที่กำหนดเองสำหรับโค้ดของคุณโดยเฉพาะ C# รองรับทั้งประเภททั่วไป (คลาส อินเทอร์เฟซ ฯลฯ) และเมธอดทั่วไป
ใน generics คุณมีพารามิเตอร์ประเภทและประเภทอาร์กิวเมนต์ ซึ่งคล้ายกับเมธอดที่มีพารามิเตอร์ และคุณส่งอาร์กิวเมนต์ไปยังเมธอด
ประเภททั่วไป
ไวยากรณ์ในการประกาศประเภททั่วไปประกอบด้วยพารามิเตอร์ประเภทในวงเล็บมุมหลังชื่อประเภท ตัวอย่างเช่น Locator
public class Locator<T>
{
}
ในการสร้างอินสแตนซ์ของ Locator
var stringLocator = new Locator<string>();
คุณสามารถใช้พารามิเตอร์ type (T) กับเมธอดของคลาสได้ดังตัวอย่างด้านล่าง
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); ประโยชน์เพิ่มเติมของยาชื่อสามัญคือ IntelliSense ที่จัดเตรียมโดยบรรณาธิการ เมื่อคุณพิมพ์ stringLocator.Locate(4) ลงใน Visual Studio หรือ VS Code แล้ววางเมาส์เหนือชื่อเมธอด มันจะแสดงให้คุณเห็นว่ามันคืนค่าสตริงแทนที่จะเป็น T หากคุณพยายามกำหนดผลลัพธ์ให้กับประเภทอื่นที่ไม่ใช่สตริง คอมไพเลอร์จะทำให้เกิดข้อผิดพลาด ตัวอย่างเช่น
// Error: Cannot implicitly convert type 'string' to 'int' [c-sharp]csharp(CS0029) int item = stringLocator.Locate(2);
ชนิดทั่วไปสามารถใช้พารามิเตอร์ type เป็นอาร์กิวเมนต์ประเภทเมื่อรับช่วงจากชนิดพื้นฐานทั่วไปหรืออินเทอร์เฟซทั่วไป ประเภท LinkedList
public class LinkedList<T> : IEnumerable<T>
วิธีการทั่วไป
วิธีการทั่วไปเป็นเพียงวิธีการที่ประกาศพารามิเตอร์ประเภทที่คุณสามารถใช้ได้ภายในวิธีการและเป็นพารามิเตอร์และประเภทการส่งคืน ในตัวอย่างด้านล่าง Swap
public class Swapper{
public T Swap<T>(T first, T second){
T temp = first;
first = second;
second = temp;
return temp;
}
} เช่นเดียวกับประเภททั่วไป เมื่อคุณเรียกใช้เมธอดทั่วไป มันจะส่งคืนตัวแปรที่พิมพ์อย่างชัดเจน
var swapper = new Swapper(); int result = swapper.Swap<int>(5, 3);
เป็นไปได้ที่จะมีพารามิเตอร์ทั่วไปหลายตัว คลาสพจนานุกรมในเนมสเปซ System.Collections.Generic มีพารามิเตอร์สองประเภท สำหรับคีย์และค่า
public class Dictionary<TKey, TValue>
สุดท้ายนี้ สิ่งสำคัญคือต้องรู้ว่าสิ่งใดสามารถเป็นแบบทั่วไปได้ สำหรับประเภท ยกเว้น enums ทุกอย่างสามารถเป็นแบบทั่วไปได้ ซึ่งรวมถึง −
- ชั้นเรียน
- โครงสร้าง
- อินเทอร์เฟซ
- ตัวแทน
สำหรับสมาชิกประเภท เมธอดและประเภทที่ซ้อนกันเท่านั้นที่สามารถเป็นแบบทั่วไปได้ สมาชิกต่อไปนี้ไม่สามารถเป็นแบบทั่วไปได้ -
- ฟิลด์
- คุณสมบัติ
- ดัชนี
- ตัวสร้าง
- เหตุการณ์
- ผู้เข้ารอบสุดท้าย
ตัวอย่าง
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;
}
} ผลลัพธ์
CSharp a = 3, b = 5