跳转至

泛型⚓︎

一、泛型概述⚓︎

泛型是将类型参数化的技术,这样就可设计具有以下特征的类和方法:在客户端代码声明并初始化这些类或方法之前,这些类或方法会延迟指定一个或多个类型。例如,通过使用泛型类型参数 T,可以编写其他客户端代码能够使用的单个类,而不会产生运行时转换或装箱操作的成本或风险。

在编程程序时,经常会遇到功能非常相似的模块,只是它们处理的数据不一样。但我们没有办法,只能分别写多个方法来处理不同的数据类型。这个时候,那么问题来了,有没有一种办法,用同一个方法来处理传入不同种类型参数的办法呢?泛型的出现就是专门来解决这个问题的。

泛型具有一下特点:

  • 使用泛型类型可以最大限度地重用代码、保护类型安全性以及提高性能。
  • 泛型最常见的用途是创建集合类。
  • .NET 类库在 System.Collections.Generic 命名空间中包含几个新的泛型集合类。
  • 可以创建自己的泛型接口、泛型类、泛型方法、泛型事件和泛型委托。
  • 可以对泛型类进行约束以访问特定数据类型的方法。
  • 在泛型数据类型中所用类型的信息可在运行时通过使用反射来获取。

二、泛型类型参数⚓︎

01 类型参数⚓︎

🔗 类型参数

02 类型参数约束⚓︎

🔗 类型参数约束

三、定义和使用泛型⚓︎

泛型类最常见用法是用于链接列表、哈希表、堆栈、队列和树等集合。 无论存储数据的类型如何,添加项和从集合删除项等操作的执行方式基本相同。

Tip

  • 通常,可参数化的类型越多,代码就越灵活、其可重用性就越高。 但过度泛化会造成其他开发人员难以阅读或理解代码。
  • 考虑使用类型约束,尽可能避免使用泛型时的其他意外。
  • 对于大多数需要集合类的方案,推荐做法是使用 .NET 类库中提供的集合类,而不是自己定义。
// 普通类
class BaseNode { }
// 泛型类
class BaseNodeGeneric<T> { }
// 多类型泛型类
class BaseNodeGeneric<TKey,TValue> { }
interface IDictionary<K, V> {}
// 普通方法
void DoWork() { }
// 泛型方法
void DoWork<T>() { } 
// 泛型可用于方法重载
void DoWork<T, U>() { } 
// 泛型委托
public delegate void Del<T>(T item);
// 方法
public static void Notify(int i) { }
// 绑定委托
Del<int> m1 = new Del<int>(Notify);
Del<int> m2 = Notify;