C# 泛型方法(原理、类型推断、多泛型参数)+泛型效率(普通类型 VS Object装箱 VS 泛型)

一、泛型核心概念(原文背诵)

泛型:广泛的不确定类型

定义方法时,不想固定参数类型、返回值类型,可以定义为泛型类型 T。

核心思想:延迟指定类型

定义方法时不锁定类型,调用方法时传入具体类型,一套代码适配所有数据类型。


二、普通方法重载(泛型优化前)

代码

复制代码
//int专用方法
static int Test(int a)
{
    return 10;
}
//string专用方法
static string Test(string a)
{
    return "ss";
}

问题痛点

如果需要支持 int、string、bool、double 等多种类型,需要写无数个重载方法,代码冗余、重复度极高。

泛型就是为了解决:不同类型、相同逻辑,不用重复写代码


三、单泛型方法(核心基础)

泛型方法定义

复制代码
//<T> 声明泛型占位符
static T Test<T>(T a)
{
    return a;
}

语法规则(必背)

  1. <T>:声明泛型,T 是类型占位符,可以换任意字母(A、B、T1、T2)

  2. 方法中所有T 代表同一个类型

  3. 参数是 T、返回值也是 T,做到:传入什么类型,返回什么类型

调用方式

复制代码
// 1.显式指定类型
Console.WriteLine(Test<int>(10));
Console.WriteLine(Test<string>("aa"));
Console.WriteLine(Test<bool>(true));

// 2.泛型类型推断(简化写法)
Console.WriteLine(Test(new string[] { "aa" })); 

两种调用方式解析

显式调用 :手动写 <类型>,清晰直观

隐式推断 :编译器根据实参自动识别类型,可以省略 <>

上面代码推断结果:string[] 类型


四、同类型双参数泛型方法 Test1<T>

代码定义

复制代码
//两个参数必须是相同类型
static T Test1<T>(T a, T b)
{
    return b;
}

规则

只有一个泛型占位符 T,所以 a、b 必须是一模一样的类型

调用代码

复制代码
Test1<int>(10, 20); //显式指定int
Test1(10, 20);       //编译器自动推断int

五、双泛型参数方法 Test2<T1,T2>

代码定义

复制代码
//两个不同泛型,无返回值
static void Test2<T1,T2>(T1 a,T2 b)
{

}

核心规则

T1、T2 是两个独立类型,可以相同、可以不同

调用解析

复制代码
Test2<int, string>(10, "aa"); //T1=int  T2=string
Test2(10, new string[] { "aa" });//T1=int  T2=string[]
Test2(10,10);//T1=int  T2=int(两个泛型可以相同)

六、返回值+数组泛型方法 Test3<T1,T2>

代码定义

复制代码
//T1为返回值类型、第一个参数类型
//T2[] 代表泛型数组
static T1 Test3<T1,T2>(T1 a, T2[] b)
{
    return a;
}

参数解析

  1. 第一个参数:普通泛型 T1

  2. 第二个参数:泛型数组 T2\[\]

  3. 返回值固定为 T1 类型

调用解析

复制代码
Test3<int, int>(10, new int[] { 1, 2, 3 }); 
//T1=int  T2=int  int数组

Test3(10, new string[] { "aa" });
//编译器自动推断 T1=int  T2=string string数组

七、泛型两大调用方式(必考)

1. 显式调用

手动指定类型:方法名<类型>(参数)

适合:类型模糊、编译器无法推断的场景

2. 隐式类型推断(简化)

直接写参数,省略 <>

编译器根据实参自动匹配泛型类型

开发中最常用


八、单泛型 VS 多泛型 核心区别

1. 单个泛型 <T>

所有 T 类型必须统一

适合:参数、返回值类型一致的场景

2. 多个泛型 <T1,T2>

T1、T2 相互独立

可以一同一不同,适配多个不同类型参数场景


九、泛型满分简答题(直接背)

1. 什么是泛型?

泛型是一种延迟确定数据类型的技术,定义方法时不固定参数和返回值类型,通过 <T> 声明占位类型,在调用方法时根据传入参数确定具体类型,实现一套代码适配多种数据类型,解决代码冗余问题。

2. 泛型的优点?

避免方法重载冗余、代码复用性高、保证类型安全、无需装箱拆箱、程序效率更高。

3. 多个泛型参数的特点?

多个泛型占位符相互独立,类型可以相同也可以不同,灵活适配多类型参数场景。


十、终极背诵口诀

泛型T是占位符,定义不把类型束

调用传参定类型,延迟绑定真舒服

单T类型必须同,多T独立互不冲

可推断可显式,一套代码通万物

---------泛型效率(普通类型 VS Object装箱 VS 泛型)------------

一、代码功能概述

本案例通过 Stopwatch 计时器,循环执行海量次数,对比三种方法的执行效率:

  • Test1:固定值类型参数 int

  • Test2:父类对象参数 object(存在装箱拆箱)

  • Test3:泛型参数T

通过实际运行耗时,验证泛型无装箱拆箱、效率接近原生值类型的核心特性。


二、完整运行结果(实测标准数据)

循环次数:1亿次

  • 普通值类型方法 Test1:3ms

  • 泛型方法 Test3:4ms

  • object装箱方法 Test2:10ms(最慢)

效率排行:固定值类型 > 泛型 > object装箱


三、三种方法逐一带底层原理解析

1. 普通值类型方法 Test1(int a)

复制代码
static void Test1(int a)
{

}
底层原理

参数直接接收 栈内存值类型,无需类型转换、无需装箱、无需拆箱。

编译时类型已经确定,运行时直接执行,效率最高。

优缺点

✅ 效率极高,无性能损耗

❌ 只能适配单一类型,复用性极差,每种类型都要重载方法


2. Object 参数方法 Test2(object a)

复制代码
static void Test2(object a)
{

}
底层原理(重难点)

C# 中 object 是所有类型的父类。

当 int 10 传给 object 参数时,发生:装箱(装箱转换)

装箱过程:

  1. 在堆中开辟新内存

  2. 将栈中 int 值拷贝到堆内存

  3. 栈上存储堆地址引用

海量循环下,频繁装箱会产生大量 GC垃圾内存,极大拖慢效率。

优缺点

✅ 可以接收任意类型,复用性高

❌存在装箱拆箱,性能极差


3. 泛型方法 Test3<T>(T a)

复制代码
static void Test3<T>(T a)
{

}
底层原理(核心考点)

泛型的本质:编译时预留类型占位,运行时根据传入类型生成专属方法。

当传入 int 类型时,CLR 会自动生成一个 Test3(int a) 专属方法。

全程无装箱、无拆箱,直接操作值类型。

优缺点

✅ 完全没有装箱拆箱损耗,效率无限接近原生值类型

✅ 一套代码适配所有类型,复用性极强

❌ 相比原生固定类型,有极其微弱的初始化损耗(几乎可忽略)


四、核心结论(必背简答题)

1. 为什么泛型比 object 效率高?

object 参数接收值类型会发生装箱拆箱 ,产生堆内存开销和 GC 压力;泛型在运行时会根据具体类型生成专属方法,全程无装箱拆箱,性能大幅提升。

2. 泛型和普通固定类型对比?

普通固定类型效率最高,但无法复用;泛型效率几乎持平原生类型,同时解决了代码复用问题,兼顾性能与复用性。

3. 泛型最大优势总结

1. 类型安全(编译时报错,不会类型转换异常)

2. 避免装箱拆箱,性能极高

3. 一套代码适配多类型,彻底解决重载冗余


五、三者终极对比表(秒杀考点)

方法类型 是否装箱拆箱 执行效率 代码复用性 适用场景
固定值类型 无 最高 差 单一固定类型逻辑
Object 参数 有(严重损耗) 最低 高 老旧框架、弱类型场景(不推荐)
泛型方法 无 极高 最高 通用工具方法、集合类、公共逻辑

六、终极背诵口诀

固定类型最快行,不能复用代码长

Object装箱速度慢,频繁GC性能伤

泛型无箱性能强,复用安全两头香

相关推荐
码匠许师傅22 分钟前
【C++三方组件】Asio 上篇:回调式 TCP 客户端与服务端
开发语言·c++·tcp/ip
神仙别闹29 分钟前
基于C语言实现 TINY+ 编译器
c语言·开发语言·数据库
mudtools32 分钟前
在.NET现有系统中快速集成飞书任务分配能力
后端·c#·.net
Wang's Blog33 分钟前
Java 项目实战: 外卖平台优化-从库Slave配置与主从复制验证
java·开发语言
知识分享小能手1 小时前
C++ 学习教程,从入门到精通,C++内存模型和名称空间 — 详细知识点总结(9)
开发语言·c++·学习
2601_962218611 小时前
c++中多重继承与虚继承的实现
开发语言·c++
我是小白呀1 小时前
17-企业Workflow引擎怎么选:定时、队列、n8n、Temporal与Camunda
java·开发语言·人工智能·dubbo·workflow
维克兜率天1 小时前
【维克】均值回归:跌多了会涨,涨多了会跌
开发语言·笔记·python·算法·均值算法·回归·量化
实心儿儿2 小时前
Qt — Qt 窗口
开发语言·qt
2601_962218612 小时前
C++中分配器allocator的实现
开发语言·c++