Menu
CoddyTech

泛型(类和方法)

本课属于 Coddy C# 学习旅程的“面向对象编程”单元。第 42 课,共 70 课。

泛型让你能够编写适用于任何数据类型的类和方法,同时保证类型安全。你只需编写一个通用类来处理所有情况,而不必分别为 IntList、StringList 和 DoubleList 编写类。

泛型类使用类型参数,通常命名为 T,并用尖括号括起来:

public class Box<T>
{
    private T content;
    
    public void Store(T item) => content = item;
    public T Retrieve() => content;
}

// 用于不同的数据类型
Box<int> intBox = new Box<int>();
intBox.Store(42);

Box<string> stringBox = new Box<string>();
stringBox.Store("Hello");

创建 Box<int> 时,编译器会将每个 T 替换为 int。这样就能在编译时进行类型检查,你不会不小心把字符串存入 int 盒子中。

泛型方法的工作方式类似,可以让一个方法处理不同的类型:

public static void Swap<T>(ref T a, ref T b)
{
    T temp = a;
    a = b;
    b = temp;
}

int x = 1, y = 2;
Swap(ref x, ref y);  // x=2, y=1

编译器会根据参数推断类型,因此你不需要显式写出 Swap<int>。泛型是 List<T> 和 Dictionary<TKey, TValue> 等集合的基础,可实现可复用且类型安全的代码。

challenge icon

挑战

简单

让我们来构建一个通用的 Storage<T> 系统,用来存储和管理任意类型的项。你将创建一个可重复使用的容器类,展示泛型的强大之处:编写一次,就能用于整数、字符串或任何其他类型!

你需要将代码分成两个文件:

  • Storage.cs:在 DataStorage 命名空间中创建一个泛型 Storage<T> 类。你的存储容器应具备以下功能:
    • 包含一个用于存储项的 T 类型私有数组,以及一个用于记录已存储项数量的 Count 属性
    • 构造函数接受一个容量参数,用于初始化内部数组
    • 包含一个 Add(T item) 方法,在有剩余空间时添加项
    • 包含一个 Get(int index) 方法,返回指定索引处的项
    • 包含一个 GetAll() 方法,返回所有已存储的项,并用 ", " 连接
  • Program.cs:在主文件中展示你的泛型类如何处理两种不同的类型。创建一个 Storage<int> 和一个 Storage<string>,分别向其中添加项,并展示同一个类如何顺畅地处理这两种类型。

你将收到 4 个输入:

  • 要存储的第一个整数
  • 要存储的第二个整数
  • 要存储的第一个字符串
  • 要存储的第二个字符串

创建一个容量为 5 的整数存储容器和一个容量为 5 的字符串存储容器。将两个整数添加到整数存储容器中,并将两个字符串添加到字符串存储容器中。

按以下格式打印输出:

Int storage: {GetAll()}
Int count: {Count}
First int: {Get(0)}
String storage: {GetAll()}
String count: {Count}
First string: {Get(0)}

例如,如果输入是 42、100、Hello 和 World,输出应为:

Int storage: 42, 100
Int count: 2
First int: 42
String storage: Hello, World
String count: 2
First string: Hello

注意,你只需编写一次 Storage<T> 类,它就能完美处理 int 和 string 两种类型,这就是泛型的妙处!编译器会确保类型安全,因此你不会意外地把字符串添加到整数存储容器中。

亲手试试

using System;
using DataStorage;

class Program
{
    public static void Main(string[] args)
    {
        // 读取输入
        int num1 = Convert.ToInt32(Console.ReadLine());
        int num2 = Convert.ToInt32(Console.ReadLine());
        string str1 = Console.ReadLine();
        string str2 = Console.ReadLine();

        // TODO: 创建一个容量为 5 的 Storage<int>
        
        // TODO: 将两个整数添加到整数存储中
        
        // TODO: 创建一个容量为 5 的 Storage<string>
        
        // TODO: 将两个字符串添加到字符串存储中
        
        // TODO: 按要求的格式打印输出
        // Int storage: {GetAll()}
        // Int 数量:{Count}
        // 第一个 int:{Get(0)}
        // String storage: {GetAll()}
        // String count: {Count}
        // First string: {Get(0)}
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C# 在线编译器