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

C#基础篇(11)泛型类与泛型方法详解

一、C# 中的泛型类详解

泛型类是 C# 中一种强大的特性,它允许你定义可以使用不同类型的类,而无需为每种类型编写单独的类。泛型类通过类型参数实现这一功能,提高了代码的重用性、类型安全性性能

1. 泛型类的基本语法

public class GenericClass<T>
{// T 是类型参数,可以在类中作为类型使用private T data;public GenericClass(T value){data = value;}public T GetData(){return data;}
}

2. 泛型类的使用

// 使用int类型实例化泛型类
GenericClass<int> intGeneric = new GenericClass<int>(10);
int intValue = intGeneric.GetData();// 使用string类型实例化泛型类
GenericClass<string> stringGeneric = new GenericClass<string>("Hello");
string stringValue = stringGeneric.GetData();

3. 泛型类的优势

  1. 类型安全​:编译时检查类型,避免运行时类型转换错误
  2. 代码重用​:一套代码可以用于多种数据类型
  3. 性能优化​:避免了装箱和拆箱操作(对于值类型)
  4. 减少强制转换​:代码更简洁,不需要频繁的类型转换

4. 多类型参数的泛型类

泛型类可以有多个类型参数:

public class Pair<TKey, TValue>
{public TKey Key { get; set; }public TValue Value { get; set; }public Pair(TKey key, TValue value){Key = key;Value = value;}
}// 使用示例
var pair = new Pair<int, string>(1, "One");

5. 泛型约束

可以为类型参数添加约束,限制可以使用的类型:

约束类型语法描述
类约束where T : classT必须是引用类型
结构约束where T : structT必须是值类型(Nullable除外)
基类约束where T : BaseClassT必须继承自BaseClass
接口约束where T : IInterfaceT必须实现IInterface
无参数构造函数约束where T : new()T必须有无参构造函数
裸类型约束where T : UT必须继承自或实现U

示例:

public class GenericClass<T> where T : IComparable, new()
{private T data;public GenericClass(){data = new T(); // 需要new()约束}public int CompareTo(T other){return data.CompareTo(other); // 需要IComparable约束}
}

6. 泛型类的继承

泛型类可以继承自其他泛型或非泛型类:

public class BaseClass<T>
{// 基类实现
}// 派生类可以是具体类型
public class DerivedClass : BaseClass<int>
{// 实现
}// 派生类也可以是泛型类
public class DerivedGenericClass<T> : BaseClass<T>
{// 实现
}// 派生类可以添加自己的类型参数
public class DerivedMultiClass<T, U> : BaseClass<T>
{// 实现
}

7. 静态成员

泛型类的静态成员是针对每个封闭类型独立的:

public class GenericClass<T>
{public static int Count { get; set; }
}// 使用示例
GenericClass<int>.Count = 10;
GenericClass<string>.Count = 20;Console.WriteLine(GenericClass<int>.Count); // 输出10
Console.WriteLine(GenericClass<string>.Count); // 输出20

8. 泛型类与反射

可以使用反射获取泛型类型信息:

Type genericType = typeof(List<>);
Type constructedType = genericType.MakeGenericType(typeof(int));
object list = Activator.CreateInstance(constructedType);

总结

C# 泛型类是一种强大的语言特性,它通过类型参数化实现了代码的高度重用,同时保持了类型安全和性能。合理使用泛型类可以:

  • 减少代码重复
  • 提高类型安全性
  • 改善性能(特别是对于值类型)
  • 创建更灵活、更通用的数据结构

在设计泛型类时,应当考虑类型约束、命名规范、文档注释等因素,以确保代码的可读性和可维护性。

二、C# 中的泛型方法详解

泛型方法是 C# 泛型编程的核心组成部分,它允许你定义可以操作多种类型的方法,而无需为每种类型编写单独的方法。泛型方法提供了类型安全代码重用的双重优势。

1. 泛型方法的基本语法

// 泛型方法定义
public T GenericMethod<T>(T parameter)
{// 方法体return parameter;
}// 使用示例
int result = GenericMethod<int>(5); // 显式指定类型
string text = GenericMethod("Hello"); // 类型推断

核心特点:

  1. 类型参数​:使用尖括号<T>声明类型参数
  2. 类型安全​:编译时类型检查
  3. 代码重用​:同一方法可用于多种类型
  4. 性能优势​:避免值类型的装箱拆箱操作

2. 泛型方法的定义方式

1. 普通类中的泛型方法

public class Utility
{public void Print<T>(T value){Console.WriteLine($"Type: {typeof(T)}, Value: {value}");}// 多类型参数public TResult Convert<TInput, TResult>(TInput input){return (TResult)Convert.ChangeType(input, typeof(TResult));}
}

2. 泛型类中的泛型方法

public class Repository<TEntity>
{// 类类型参数TEntity与方法类型参数T是独立的public T Execute<T>(Func<TEntity, T> selector){// 实现...}
}

3. 静态类中的泛型方法

public static class MathUtils
{public static T Max<T>(T a, T b) where T : IComparable<T>{return a.CompareTo(b) > 0 ? a : b;}
}

4. 接口中的泛型方法

public interface IProcessor
{TResult Process<TInput, TResult>(TInput input);
}

3. 泛型方法的类型参数约束

约束可以限制可用于泛型方法的类型参数,提供更强的类型安全和功能支持。

常用约束类型

约束类型语法示例说明
类约束where T : classT必须是引用类型
结构约束where T : structT必须是值类型(Nullable除外)
基类约束where T : BaseClassT必须继承自BaseClass
接口约束where T : IInterfaceT必须实现IInterface
无参构造函数约束where T : new()T必须有无参构造函数
裸类型约束where T : UT必须继承自或实现U

约束组合示例

public T CreateAndCompare<T>(T value) where T : class, IComparable<T>, new()
{T newInstance = new T();return value.CompareTo(newInstance) > 0 ? value : newInstance;
}

4. 泛型方法的高级特性

1. 类型推断

C#编译器通常可以推断泛型方法的类型参数,无需显式指定:

// 不需要指定<int>,编译器从参数推断
int max = MathUtils.Max(5, 10); 

2. 泛型方法与重载

泛型方法可以与非泛型方法重载:

public class Printer
{public void Print<T>(T value) { /* 泛型实现 */ }public void Print(int value) { /* 特定类型实现 */ }
}

调用时,编译器会优先选择最具体的匹配。

3. 递归泛型方法

泛型方法可以递归调用自身:

public static T[] BubbleSort<T>(T[] array) where T : IComparable<T>
{for (int i = 0; i < array.Length - 1; i++){if (array[i].CompareTo(array[i + 1]) > 0){T temp = array[i];array[i] = array[i + 1];array[i + 1] = temp;return BubbleSort(array); // 递归调用}}return array;
}

4. 协变和逆变(C# 4.0+)

使用inout修饰符:

// 协变返回类型
public interface IFactory<out T>
{T Create();
}// 逆变参数
public interface IComparer<in T>
{int Compare(T x, T y);
}

5. 泛型方法与反射

可以通过反射调用泛型方法:

public class ReflectionExample
{public static void CallGenericMethod(){var method = typeof(Utility).GetMethod("Print");var genericMethod = method.MakeGenericMethod(typeof(int));genericMethod.Invoke(null, new object[] { 42 });}
}

总结

C# 泛型方法是强大的编程工具,它:

  1. 提高了代码的重用性类型安全
  2. 消除了强制转换的需要
  3. 为值类型提供了更好的性能
  4. 使API设计更加灵活表达力强

合理使用泛型方法可以显著提高代码质量,但也要注意避免过度复杂化。掌握泛型方法的使用是成为高级C#开发者的重要一步。

http://www.lryc.cn/news/583065.html

相关文章:

  • 1068.产品销售分析Ⅰ
  • huggingface 笔记: Trainer
  • 打造自己的组件库(二)CSS工程化方案
  • 跨服务sqlplus连接oracle数据库
  • 54页|PPT|新型数字政府综合解决方案:“一网 一云 一中台 N应用”平台体系 及“安全+运营”服务体系
  • 人工智能的基石:TensorFlow与PyTorch在图像识别和NLP中的应用
  • 影石(insta360)X4运动相机视频删除的恢复方法
  • 【视频观看系统】- 需求分析
  • 【DB2】load报错SQL3501W、SQL3109N、SQL2036N
  • Tensorflow的安装记录
  • django 一个表中包括id和parentid,如何通过parentid找到全部父爷id
  • react+ts 移动端页面分页,触底加载下一页
  • 板凳-------Mysql cookbook学习 (十一--------6)
  • 安卓设备信息查看器 - 源码编译
  • Android-重学kotlin(协程源码第二阶段)新学习总结
  • 中望CAD2026亮点速递(5):【相似查找】高效自动化识别定位
  • uniapp AndroidiOS 定位权限检查
  • Android ViewModel机制与底层原理详解
  • upload-labs靶场通关详解:第19关 条件竞争(二)
  • 池化思想-Mysql异步连接池
  • 5.注册中心横向对比:Nacos vs Eureka vs Consul —— 深度解析与科学选型指南
  • Web 前端框架选型:React、Vue 和 Angular 的对比与实践
  • 华为静态路由配置
  • 小米路由器3C刷OpenWrt,更换系统/变砖恢复 指南
  • 语音识别核心模型的数学原理和公式
  • 从互联网电脑迁移Dify到内网部署Dify方法记录
  • 【编程史】IDE 是谁发明的?从 punch cards 到 VS Code
  • 计算机网络实验——访问H3C网络设备
  • Java项目集成Log4j2全攻略
  • Using Spring for Apache Pulsar:Publishing and Consuming Partitioned Topics