VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 泛型——类型安全的复用

泛型类与泛型方法

  1. 泛型的核心概念与价值
    泛型是C#中用于创建类型无关、可重用代码的工具,核心解vb.net教程C#教程python教程SQL教程access 2010教程决以下问题:
    类型安全:避免使用object类型导致的隐式类型转换错误;
    性能优化:消除装箱/拆箱操作(值类型转object的开销);
    代码复用:一套逻辑适配多种数据类型,减少重复代码。
    泛型通过类型参数(如)实现,编译时会根据实际类型生成特定版本的代码,保证类型安全与性能。
  2. 泛型类:通用容器的实现
    泛型类是包含类型参数的类,可适配任意数据类型。以下以通用列表容器MyList为例,展示泛型类的定义与使用。
    2.1 非泛型vs泛型:问题对比
    非泛型列表(如MyIntList)仅支持单一类型,代码复用性差:
    csharp
	// 非泛型:仅支持int类型的列表
	public class MyIntList
	{
	private int[] _items;
	private int _count;
	public MyIntList() { _items = new int[10]; _count = 0; }
	public void Add(int item) { _items[_count++] = item; }
	public int Get(int index) { return _items[index]; }
	}

泛型列表MyList支持任意类型,代码复用性强:
csharp

	// 泛型类:支持任意类型的列表
	public class MyList<T>
	{
	private T[] _items; // T为类型参数,编译时替换为实际类型
	private int _count;
	
	// 构造函数:初始化数组
	public MyList() 
	{ 
	_items = new T[10]; // 创建T类型的数组
	_count = 0; 
	}
	
	// 添加元素:接收T类型参数
	public void Add(T item) 
	{ 
	if (_count >= _items.Length) Array.Resize(ref _items, _items.Length*2);
	_items[_count++] = item; 
	}
	
	// 获取元素:返回T类型
	public T Get(int index) 
	{ 
	if (index <0 || index >= _count) throw new IndexOutOfRangeException();
	return _items[index]; 
	}
	
	// 元素数量:只读属性
	public int Count => _count;
	}

2.2 泛型类的使用与逐行讲解
csharp

	class Program
	{
	static void Main()
	{
	// 1. 泛型类实例化:指定类型参数为int
	MyList<int> intList = new MyList<int>();
	intList.Add(10);
	intList.Add(20);
	Console.WriteLine($"intList第0个元素:{intList.Get(0)}"); // 输出10
	
	// 2. 指定类型参数为string
	MyList<string> strList = new MyList<string>();
	strList.Add("Hello");
	strList.Add("泛型");
	Console.WriteLine($"strList第1个元素:{strList.Get(1)}"); // 输出"泛型"
	
	// 3. 指定类型参数为自定义类
	MyList<Person> personList = new MyList<Person>();
	personList.Add(new Person("张三",25));
	Console.WriteLine($"personList第0个元素:{personList.Get(0).Name}"); // 输出"张三"
	}
	}
	
	// 自定义类
	public class Person
	{
	public string Name { get; set; }
	public int Age { get; set; }
	public Person(string name, int age) { Name = name; Age = age; }
	}

逐行讲解:
MyList intList:实例化泛型类时,用指定类型参数,编译器生成MyList的专用版本;
intList.Add(10):Add方法接收int类型参数,无类型转换;
MyList:支持自定义类,体现泛型的通用性;
无装箱/拆箱操作:值类型(如int)直接存储,引用类型(如string、Person)存储地址,性能更高。
3. 泛型方法:类型无关的函数
泛型方法是包含类型参数的方法,可独立于类使用(静态/实例方法均可)。以下以Swap(交换两个变量)为例说明。
3.1 泛型方法的定义与使用
csharp

	public class GenericHelper
	{
	// 泛型方法:交换两个变量的值
	public static void Swap<T>(ref T a, ref T b)
	{
	T temp = a; // T为类型参数,适配任意类型
	a = b;
	b = temp;
	}
	
	// 泛型方法:查找数组中的第一个元素
	public static T FindFirst<T>(T[] array)
	{
	if (array == null || array.Length ==0) throw new ArgumentNullException();
	return array[0];
	}
	}
	
	// 使用示例
	class Program
	{
	static void Main()
	{
	// 交换int变量
	int x=10, y=20;
	GenericHelper.Swap(ref x, ref y);
	Console.WriteLine($"x={x}, y={y}"); // 输出x=20,y=10
	
	// 交换string变量
	string s1="A", s2="B";
	GenericHelper.Swap(ref s1, ref s2);
	Console.WriteLine($"s1={s1}, s2={s2}"); // 输出s1=B,s2=A
	
	// 查找数组第一个元素
	double[] nums = {3.14, 1.59, 2.65};
	Console.WriteLine($"第一个元素:{GenericHelper.FindFirst(nums)}"); // 输出3.14
	}
	}

逐行讲解:
static void Swap(ref T a, ref T b):是方法的类型参数,需放在返回类型前;
ref T a:使用ref关键字传递变量引用,确保交换生效;
GenericHelper.Swap(ref x, ref y):调用时无需显式指定(编译器自动推断类型);
通用性:同一Swap方法适配int、string、自定义类等任意类型。
4. 泛型约束:限制类型参数范围
泛型约束通过where关键字限制类型参数的合法范围,确保泛型代码可调用特定方法/属性。常见约束如下:
4.1 常用约束类型
约束语法 作用说明
where T : class T必须是引用类型(如string、类)
where T : struct T必须是值类型(如int、double)
where T : new() T必须有默认构造函数(无参)
where T : BaseClass T必须继承自BaseClass
where T : IInterface T必须实现IInterface接口
4.2 约束实例:带比较的泛型类
以下示例要求类型参数T实现IComparable接口(支持比较操作):
csharp

	// 泛型类:查找数组中的最大值
	public class MaxFinder<T> where T : IComparable<T>
	{
	public static T FindMax(T[] array)
	{
	if (array == null || array.Length ==0) throw new ArgumentNullException();
	T max = array[0];
	foreach (var item in array)
	{
	if (item.CompareTo(max) >0) max = item; // 调用IComparable<T>的CompareTo方法
	}
	return max;
	}
	}
	
	// 使用示例
	class Program
	{
	static void Main()
	{
	int[] ints = {5,2,9,1};
	Console.WriteLine($"int最大值:{MaxFinder<int>.FindMax(ints)}"); // 输出9
	
	string[] strs = {"apple", "banana", "cherry"};
	Console.WriteLine($"string最大值:{MaxFinder<string>.FindMax(strs)}"); // 输出"cherry"
	}
	}

讲解:
where T : IComparable:确保T类型支持比较,否则CompareTo方法无法调用;
int、string均实现IComparable接口,因此可直接使用;
若传入未实现该接口的类型(如自定义类未实现IComparable),编译时会报错,保证类型安全。
5. 基础知识拓展
5.1 泛型的协变与逆变
C#通过out(协变)和in(逆变)关键字,允许泛型类型在继承关系中的灵活转换:
协变(out):用于输出类型(如返回值),允许将IEnumerable赋值给IEnumerable

本站原创,转载请注明出处:

 


相关教程