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