当前位置: 首页 > news >正文

C# 泛型

# 一、泛型方法中 <T> 的含义与作用
1. **<T> 表示类型参数**
T 是一个**占位符**,代表**任意一种数据类型**。
在方法定义时不确定具体类型,调用时才确定。
2. **T 可以是任意类型**
包括:
- 值类型:int、double、bool、char、struct
- 引用类型:string、类、数组、接口

、、、csharp

using System;

class Program
{
// 定义泛型方法,<T> 为类型占位符
public static void ShowInfo<T>(T data)
{
Console.WriteLine($"数据值:{data},数据类型:{typeof(T)}");
}

static void Main()
{
// 1. 值类型调用
ShowInfo<int>(100);
ShowInfo<double>(3.14);
ShowInfo<bool>(true);
ShowInfo<char>('A');

// 2. 引用类型调用
ShowInfo<string>("测试字符串");
ShowInfo<object>(new object());

// 编译器可自动推断类型,省略 <T>
ShowInfo(666);
ShowInfo("自动推断类型");

Console.ReadKey();
}
}


3. **类型推导机制**
调用泛型方法时,**编译器会根据传入参数自动推导 T 的类型**,
不需要手动写 <int> / <string>。
4. **泛型的核心优势**
一套代码,支持所有类型,**避免重复代码、避免类型转换、提高安全性**。

、、、csharp

using System;

class GenericDemo
{
// 泛型方法
public static void PrintData<T>(T value)
{
Console.WriteLine($"值:{value},类型:{typeof(T).Name}");
}

static void Main()
{
// 1. 类型推导:省略 <类型>,编译器自动识别
PrintData(100); // 自动推导 T = int
PrintData(3.14); // 自动推导 T = double
PrintData("Hello"); // 自动推导 T = string
PrintData(true); // 自动推导 T = bool

// 也可以手动指定类型,两种写法都合法
PrintData<string>("手动指定字符串类型");

// 对比:不用泛型,需要写多个重载方法,代码冗余
// public static void Print(int a){}
// public static void Print(double a){}
// public static void Print(string a){}

Console.ReadKey();
}
}


# 二、泛型的重要限制:未约束 T 不能直接使用 + 运算符
1. **未约束的泛型 T,编译器不知道它是什么类型**
不知道是否支持 `+`、`-`、`*`、`/` 等运算符。
2. **直接对 T 类型变量做数学运算会编译报错**
因为编译器无法验证运算是否合法。
3. **解决方式**
- 使用**泛型约束**
- 使用动态类型 dynamic
- 使用运算符重载或第三方库辅助
4. **核心结论(必背)**
**无约束的泛型 T 不能直接进行算术运算。**

、、、csharp

using System;

class Program
{
// 无约束泛型方法
public static void Calc<T>(T a, T b)
{
// 编译报错:无约束 T 不能直接使用 + 运算符
// T result = a + b;
}

// 方式1:使用 dynamic 绕过限制
public static void AddByDynamic<T>(T a, T b)
{
dynamic d1 = a;
dynamic d2 = b;
var res = d1 + d2;
Console.WriteLine($"运算结果:{res}");
}

static void Main()
{
AddByDynamic(10, 20);
AddByDynamic(3.14, 2.86);

Console.ReadKey();
}
}


# 三、方法重载优先级:固定类型方法 > 泛型方法
1. **同一个类中,普通方法(固定类型)与泛型方法可构成重载**
2. **重载匹配规则(考试必考)**
**精确匹配的普通方法 > 泛型方法**
传入 int → 优先调用 int 方法
传入 string → 优先调用 string 方法
无精确匹配时,才会调用泛型方法。
3. **为什么?**
普通方法是**明确类型**,泛型是**通用类型**,
编译器永远优先选择**最具体、最精确**的方法。
4. **必背结论**
**固定类型方法优先级 > 泛型方法。**

、、、csharp

using System;

class Test
{
// 普通 int 类型方法
public static void Show(int num)
{
Console.WriteLine("调用 int 普通方法:" + num);
}

// 普通 string 类型方法
public static void Show(string str)
{
Console.WriteLine("调用 string 普通方法:" + str);
}

// 泛型方法
public static void Show<T>(T data)
{
Console.WriteLine($"调用泛型方法,类型:{typeof(T).Name},值:{data}");
}

static void Main()
{
// 1. 精确匹配,优先执行对应普通方法
Show(100);
Show("C#");

// 2. 无对应普通方法,才会调用泛型方法
Show(3.14);
Show(true);

Console.ReadKey();
}
}


# 四、泛型类继承普通类(非泛型类)的规则
1. **泛型类可以继承非泛型(普通)类**
语法:`class GenericClass<T> : NormalClass`
2. **继承后,父类成员完全可用**
子类可以直接访问父类的字段、属性、方法。
3. **泛型参数 T 只作用于当前泛型类,不影响父类**
父类是普通类,与 T 无关。
T 只在子类内部生效。
4. **语法合法、使用广泛**
常用于:通用工具类、通用管理类、通用模型。
5. **核心结论**
**泛型类可以正常继承非泛型类,继承关系不受泛型影响。**

、、、csharp

using System;

// 非泛型父类(普通类)
class ParentClass
{
public string Name { get; set; }

public void SayHello()
{
Console.WriteLine("来自普通父类的方法:Hello");
}
}

// 泛型子类 继承 普通父类
class ChildClass<T> : ParentClass
{
// 泛型类独有的泛型成员
public T Data { get; set; }

public void ShowData()
{
Console.WriteLine($"泛型数据:{Data},类型:{typeof(T).Name}");
}
}

class Program
{
static void Main()
{
// 使用 int 作为泛型参数
ChildClass<int> obj1 = new ChildClass<int>();
// 调用父类属性和方法
obj1.Name = "测试1";
obj1.SayHello();
// 调用自身泛型成员
obj1.Data = 100;
obj1.ShowData();

Console.WriteLine("------------------");

// 使用 string 作为泛型参数
ChildClass<string> obj2 = new ChildClass<string>();
obj2.Name = "测试2";
obj2.SayHello();
obj2.Data = "泛型字符串";
obj2.ShowData();

Console.ReadKey();
}
}


# 五、四条知识点 终极精简背诵版(最适合记忆)
1. **<T> = 类型参数,调用时自动推导,支持任意类型。**
2. **无约束 T 不能直接运算,因为编译器不知道类型。**
3. **方法重载:普通固定类型方法 优先于 泛型方法。**
4. **泛型类可继承普通类,父类不受 T 影响,子类正常使用父类成员。**

http://www.gsyq.cn/news/1429795.html

相关文章:

  • C++之父开撕AI Coding:资深开发者宁愿退休也不愿伺候AI生成的代码
  • 为什么你的论文参考文献格式总是不对?3个GB/T 7714 BibTeX样式终极解决方案
  • 187、运动控制中的行业应用:机械臂力控打磨
  • 前端内存泄漏常见场景与排查
  • GTA5线上小助手:免费开源工具帮你轻松称霸洛圣都终极指南
  • Kettle官网大变样?别慌!手把手教你找到最新9.3版本的下载入口(附Hadoop Shims获取指南)
  • 【AI+房地产实战指南】:2024年最值得落地的7大智能整合场景与避坑清单
  • ARP 协议:网络世界里的“地址翻译官“
  • SBM-20-1盖革管3D打印端盖制作:从零打造专业级辐射探测器接口
  • 2026AI漫剧创作深度测评:如何为你的创作需求匹配最佳方案? - 速递信息
  • 189、运动控制中的行业应用:医疗设备(手术机器人)
  • 英雄联盟R3nzSkin换肤工具实战指南:国服安全自定义皮肤完整方案
  • yuzu模拟器架构深度解析:从Switch硬件仿真到跨平台渲染优化
  • 2026年AI漫剧创作推荐榜:主流工具平台深度测评,优质品牌选型指南 - 速递信息
  • Translumo:专为游戏玩家设计的屏幕实时翻译工具,打破语言障碍的终极解决方案
  • 平台算法审核已升级!你的AI视频正被自动标记为“潜在侵权内容”(附2024主流平台检测逻辑逆向分析)
  • TPAMI 2026 | DC-SAM 横空出世!融合 SAM 特征,打造图像视频通用上下文分割框架
  • 2026年专业做床垫的公司哪家强?南宁市雅兰床垫值得一探! - 资讯快报
  • 2026年华为OD机试(A卷,100分)- 机器人(Java JS Python)带详细答案和源码
  • 终极JSON转Java实体类工具:3分钟掌握GsonFormatPlus完整使用指南
  • 虚表 —— 表头多按钮示例
  • 别再对着空白界面发愁了!手把手教你用AVL Cruise自带模型快速搞定纯电动车仿真
  • AI漫剧制作平台2026服务与实力盘点 - 速递信息
  • AI行业进入“夏天”:多公司融资扩张,多维度打分揭示发展阶段与入场策略
  • 周四日子
  • 校园快递信息管理系统
  • 2026年小红书营销:如何用AI降CPA?
  • ESP32+GC9A01圆形屏播放视频,为什么你的TF卡读不出来?SPI引脚配置详解与排查指南
  • 2026二氧化碳减压阀品牌推荐:进口国产对比与高性价比选型指南 - 资讯纵览
  • 别再折腾蓝屏了!用这个一键脚本在Ubuntu 18.04上搞定Xrdp远程桌面