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

การทำงานของ Generics ใน C#


Generics เพิ่มใน C# 2.0 เป็นแนวคิดสำคัญที่สุด ช่วยเขียนโค้ด Reusable, High-Performance, Type-Safe ตอน Compile-time ใช้ Type ในโค้ดโดยไม่ต้องรู้ Type ล่วงหน้า

Generics ใช้ทั่วไปใน .NET: Collections, Delegates, Async Code ไม่ต้องรู้ขนาด Collection ล่วงหน้า ใช้กับ Element Type ใดๆ รวมถึง Custom Types C# รองรับทั้ง Generic Types (Class, Interface ฯลฯ) และ Generic Methods

ใน Generics มี Type Parameters และ Type Arguments คล้าย Method ที่มี Parameters และ Arguments

Generic Types

Syntax: ชื่อ Type ตามด้วย Type Parameters ใน Angle Brackets เช่น Locator<T>

public class Locator<T> { }

สร้าง Instance โดยระบุ Type Argument จริง:

var stringLocator = new Locator<string>();

ใช้ Type Parameter (T) ใน Method ของ Class:

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

ประโยชน์เพิ่ม: IntelliSense ใน Editor จะแสดง Return Type เป็น string (ไม่ใช่ T) หาก Assign ให้ Type อื่น Compiler Error

// Error: Cannot convert 'string' to 'int'
int item = stringLocator.Locate(2);

Generic Type ใช้ Type Parameter เป็น Type Argument เมื่อ繼承 Generic Base Type หรือ Interface:

public class LinkedList<T> : IEnumerable<T>

Generic Methods

Generic Method ประกาศ Type Parameter ใช้ภายใน Method และเป็น Parameter/Return Type เช่น Swap<T>:

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

เรียกใช้ Generic Method ได้ Strongly Typed Variable:

var swapper = new Swapper();
int result = swapper.Swap<int>(ref a, ref b);

สามารถมี Multiple Generic Parameters ได้ เช่น Dictionary<TKey, TValue>

สิ่งที่สามารถเป็น Generic ได้:

  • Types (ยกเว้น Enum): Class, Struct, Interface, Delegate
  • Type Members: เฉพาะ Methods และ Nested Types

สิ่งที่ ไม่สามารถ เป็น Generic: Fields, Properties, Indexers, Constructors, Events, Finalizers

ตัวอย่างโค้ด

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var stringLocator = new Locator<string>()
        {
            Items = new string[] { "JavaScript", "CSharp", "Golang" }
        };
        Console.WriteLine(stringLocator.Locate(1)); // 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}"); // a = 3, b = 5
    }
}

public class Locator<T>
{
    public IList<T> Items { get; set; }
    public T Locate(int index) => 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