C# 泛型(Generic)完全指南:从基础到高级应用

在现代 C# 开发中,**泛型(Generic)**是提升代码复用性、类型安全和性能的重要工具。通过泛型,你可以编写与具体数据类型无关的类、方法、委托或接口,从而让程序更加灵活和高效。本文将从基础概念、语法、实例到高级约束与最佳实践,系统讲解泛型在 C# 中的应用。


一、什么是泛型

泛型的核心思想是:延迟指定数据类型。传统类或方法在编写时就固定了数据类型,而泛型允许你在使用时再指定类型。例如,你可以写一个"通用数组类",既可以存储整数,也可以存储字符串或自定义类型,而不需要为每种类型都写一个新类。

泛型的优势:

  • 类型安全:编译器会在编译阶段检查类型,减少运行时错误。
  • 提高复用性:一份代码可适配多种类型。
  • 性能优化:避免值类型装箱与拆箱,提高运行效率。
  • 简化 API:与非泛型集合相比,代码更简洁直观。

二、泛型类

泛型类是最常见的泛型形式。下面用一个自定义泛型数组类来演示:

csharp 复制代码
using System;

namespace GenericDemo
{
    public class MyGenericArray<T>
    {
        private T[] array;

        public MyGenericArray(int size) => array = new T[size];

        public void SetItem(int index, T value) => array[index] = value;

        public T GetItem(int index) => array[index];
    }

    class Program
    {
        static void Main()
        {
            // 整型数组
            var intArray = new MyGenericArray<int>(5);
            for (int i = 0; i < 5; i++) intArray.SetItem(i, i * 10);
            for (int i = 0; i < 5; i++) Console.Write(intArray.GetItem(i) + " ");
            Console.WriteLine();

            // 字符数组
            var charArray = new MyGenericArray<char>(5);
            for (int i = 0; i < 5; i++) charArray.SetItem(i, (char)('A' + i));
            for (int i = 0; i < 5; i++) Console.Write(charArray.GetItem(i) + " ");
        }
    }
}

输出结果:

复制代码
0 10 20 30 40
A B C D E

分析

  1. T 是类型参数,占位符类型。
  2. 在创建对象时,intchar 被替换到 T,编译器会生成对应类型的具体实现。
  3. 泛型保证了类型安全,避免了手动类型转换。

三、泛型方法

泛型方法的类型参数只对该方法有效,而不依赖于类的泛型参数。典型例子是交换两个变量的值:

csharp 复制代码
using System;

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

    static void Main()
    {
        int x = 5, y = 10;
        char c1 = 'X', c2 = 'Y';

        Swap<int>(ref x, ref y);
        Swap<char>(ref c1, ref c2);

        Console.WriteLine($"x={x}, y={y}");
        Console.WriteLine($"c1={c1}, c2={c2}");
    }
}

输出结果:

复制代码
x=10, y=5
c1=Y, c2=X

泛型方法提高了函数的灵活性,无论整数、字符甚至自定义类都可以直接使用。


四、泛型委托

泛型不仅适用于类和方法,也可以用于委托,实现类型安全的回调机制。例如:

csharp 复制代码
using System;

delegate T Operation<T>(T value);

class GenericDelegateDemo
{
    static int AddTen(int x) => x + 10;
    static int MultiplyByTwo(int x) => x * 2;

    static void Main()
    {
        Operation<int> add = AddTen;
        Operation<int> multiply = MultiplyByTwo;

        Console.WriteLine(add(5));        // 输出 15
        Console.WriteLine(multiply(5));   // 输出 10
    }
}

泛型委托可适配多种类型的操作,并确保类型安全,避免了非泛型委托可能出现的类型转换异常。


五、泛型约束

在实际开发中,有时需要限制泛型类型以满足特定条件,例如只能是引用类型或值类型。C# 提供了丰富的约束选项:

约束 说明
where T : struct 必须是值类型(非 Nullable)
where T : class 必须是引用类型
where T : new() 必须有无参数构造函数
where T : BaseClass 必须继承自指定类
where T : IInterface 必须实现指定接口,可组合多个接口

示例:

csharp 复制代码
public class Factory<T> where T : new()
{
    public static T Create() => new T();
}

class Person { public string Name; }
class Program
{
    static void Main()
    {
        var person = Factory<Person>.Create();
        person.Name = "张三";
        Console.WriteLine(person.Name);
    }
}

分析

  • new() 约束保证 T 可通过 new T() 实例化。
  • 泛型约束可以组合,例如 where T : class, IComparable, new()

六、泛型的应用场景

泛型在以下场景最常用:

  1. 集合类 :如 List<T>Dictionary<TKey,TValue>
  2. 缓存管理 :如 CacheHelper<T> 类可以存取任意类型的缓存对象。
  3. 通用工具类:排序、查找、比较等算法。
  4. 事件与回调:泛型委托提高事件处理的灵活性和类型安全。

七、泛型的性能与注意事项

  • 泛型在编译期生成具体类型代码,不会增加运行时开销。
  • 使用值类型泛型可避免装箱操作,性能优于非泛型集合。
  • 泛型约束有助于提供编译期检查,减少运行时错误。
  • 注意不要过度泛型化,复杂的泛型嵌套会降低可读性。

八、总结

C# 泛型是提升代码复用性、类型安全和性能的重要工具。掌握泛型类、泛型方法、泛型委托以及约束,你可以编写更加灵活、健壮、高效的程序。

核心要点:

  • 泛型通过类型参数延迟指定类型。
  • 泛型方法和泛型委托提升函数和回调的灵活性。
  • 泛型约束保证类型安全,便于公共组件开发。
  • 应用泛型集合可以替代传统非泛型集合,避免类型转换问题。

泛型是现代 C# 开发的基础技能,理解并熟练使用它,可以让你的程序更优雅、更专业。

相关推荐
我是唐青枫2 小时前
C#.NET Memory 深入解析:跨异步边界的内存视图与高性能实战
开发语言·c#·.net
人工智能AI技术2 小时前
AI Gateway 实战:基于 C# 与 YARP 构建多模型统一接入与路由网关
人工智能·c#
njsgcs6 小时前
solidworks 导出dwg 带映射模板 c# 图纸比例一比一导出
c#·solidworks
人工智能AI技术6 小时前
美团“问小团”同款架构:C# + ASP.NET Core 搭建本地生活 AI 搜索
人工智能·c#
!chen8 小时前
C# + ViewFaceCore 快速实现高精度人脸识别
开发语言·c#
她说彩礼65万8 小时前
WPF DataContext详解及用例
c#
她说彩礼65万8 小时前
WPF Dispatcher和DispatcherObject
c#
“抚琴”的人9 小时前
SqlSugar 文档
开发语言·数据库·c#·sqlsugar
人工智能AI技术9 小时前
从0到1:C# 调用 Claude 插件打通 Excel 与 PowerPoint 工作流
人工智能·c#