Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

อธิบายว่ายาชื่อสามัญทำงานอย่างไรใน C#


Generics ถูกเพิ่มในเวอร์ชัน 2.0 ของ C# และเป็นหนึ่งในแนวคิดที่สำคัญที่สุดในภาษา สิ่งเหล่านี้ทำให้คุณสามารถเขียนโค้ดที่นำกลับมาใช้ใหม่ได้ ประสิทธิภาพสูง ซึ่งปลอดภัยต่อการพิมพ์ในขณะที่คอมไพล์ เมื่อใช้ชื่อสามัญ คุณจะใช้ประเภทในโค้ดได้โดยไม่ต้องทราบล่วงหน้า

Generics ถูกใช้ในหลายที่ใน .NET รวมถึงคอลเล็กชัน ผู้รับมอบสิทธิ์ และโค้ดแบบอะซิงโครนัส คุณไม่จำเป็นต้องทราบขนาดของคอลเล็กชันล่วงหน้า และคุณสามารถใช้ข้อมูลทั่วไปกับองค์ประกอบประเภทใดก็ได้ แม้แต่ประเภทข้อมูลที่กำหนดเองสำหรับโค้ดของคุณโดยเฉพาะ C# รองรับทั้งประเภททั่วไป (คลาส อินเทอร์เฟซ ฯลฯ) และเมธอดทั่วไป

ใน generics คุณมีพารามิเตอร์ประเภทและประเภทอาร์กิวเมนต์ ซึ่งคล้ายกับเมธอดที่มีพารามิเตอร์ และคุณส่งอาร์กิวเมนต์ไปยังเมธอด

ประเภททั่วไป

ไวยากรณ์ในการประกาศประเภททั่วไปประกอบด้วยพารามิเตอร์ประเภทในวงเล็บมุมหลังชื่อประเภท ตัวอย่างเช่น Locator เป็นคลาสทั่วไปในตัวอย่างด้านล่าง

public class Locator<T>
{

}

ในการสร้างอินสแตนซ์ของ Locator คุณต้องใช้คำหลักใหม่ ตามด้วยชื่อของคลาส อย่างไรก็ตาม แทนที่จะเป็น T คุณต้องระบุประเภทจริงที่คุณต้องการส่งเป็นอาร์กิวเมนต์ ตัวอย่างต่อไปนี้ส่งผ่านประเภทสตริงเป็นอาร์กิวเมนต์

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 ทั่วไปใช้อินเทอร์เฟซ IEnumerable ทั่วไปพร้อมกับส่วนอื่นๆ

public class LinkedList<T> : IEnumerable<T>

วิธีการทั่วไป

วิธีการทั่วไปเป็นเพียงวิธีการที่ประกาศพารามิเตอร์ประเภทที่คุณสามารถใช้ได้ภายในวิธีการและเป็นพารามิเตอร์และประเภทการส่งคืน ในตัวอย่างด้านล่าง Swap เป็นวิธีการทั่วไปที่ใช้พารามิเตอร์ประเภท T สองตัวและส่งคืนอินสแตนซ์ของ T

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