C#学习10——泛型
一、什么是泛型?
官方理解:允许开发者在定义类、接口、方法或委托时使用类型参数
个人理解: 类型模具(类似Object变色龙)
二、泛型有什么用?
通过参数化类型实现代码复用,提升类型安全性并避免运行时类型转换开销(如装箱/拆箱),同时保持编译时类型检查,清晰的意图:明确表示代码可以处理多种类型
三、泛型的定义
1)泛型类 :
class 类名<T>{} new 类名<int>();
eg:
using System;
using LearnC_;
namespace HelloWorld
{class Program{static void Main(string[] args){// 创建一个整数类型的 Pairvar intPair = new Pair<int>(1, 2);intPair.DisplayPair(); // 输出: Pair: (1, 2)// 创建一个字符串类型的 Pairvar stringPair = new Pair<string>("Hello", "World");stringPair.DisplayPair(); // 输出: Pair: (Hello, World)}}public class Pair<T>{public T First { get; set; }public T Second { get; set; }public Pair(T first, T second){First = first;Second = second;}public void DisplayPair(){Console.WriteLine($"Pair: ({First}, {Second})");}}
}
2)泛型方法: public static T 方法名<T >(T 参数){} 方法名.(参数)
eg:
using System;
namespace HelloWorld
{class Program{ public static T GenericIdentity<T>(T input){return input;}static void Main(string[] args){// 调用泛型方法int intResult = GenericIdentity(42);Console.WriteLine($"整数结果: {intResult}"); // 输出: 整数结果: 42string stringResult = GenericIdentity("Hello, Generics!");Console.WriteLine($"字符串结果: {stringResult}"); // 输出: 字符串结果: Hello, Generics!}}
}
3)泛型接口: interface 接口名<T>{} 类名:接口名<类型>{}
eg:
using System;
namespace HelloWorld
{// 定义一个泛型接口public interface IContainer<T>{T Value { get; set; }}// 实现泛型接口的类public class SimpleContainer<T> : IContainer<T>{public T Value { get; set; }public SimpleContainer(T value){Value = value;}}class Program{ static void Main(string[] args){// 创建一个整数类型的容器IContainer<int> intContainer = new SimpleContainer<int>(10);Console.WriteLine($"整数容器中的值是: {intContainer.Value}"); // 输出: 整数容器中的值是: 10// 创建一个字符串类型的容器IContainer<string> stringContainer = new SimpleContainer<string>("Hello, Generic Interface!");Console.WriteLine($"字符串容器中的值是: {stringContainer.Value}"); // 输出: 字符串容器中的值是: Hello, Generic Interface!}}}
4)泛型委托:
约束类型 示例 说明
where T : struct public class C<T> where T : struct 限制 T 为值类型(非 null)。
where T : class public class C<T> where T : class 限制 T 为引用类型(可为 null)。
where T : new() public class C<T> where T : new() 限制 T 必须有无参构造函数。
where T : BaseClass public class C<T> where T : BaseClass 限制 T 必须继承自 BaseClass。
where T : IInterface public class C<T> where T : IInterface 限制 T 必须实现 IInterface。
where T : U public class C<T, U> where T : U 限制 T 必须继承或实现 U。
eg:
1. where T : struct
- 用途:限制类型参数
T
必须是值类型(如int
、double
、自定义结构体等)。 - 示例:
public class Example<T> where T : struct { public void PrintType() { Console.WriteLine(typeof(T).Name); } }// 使用示例 var intExample = new Example<int>(); // 合法 var stringExample = new Example<string>(); // 编译错误:string 是引用类型
2. where T : class
- 用途:限制类型参数
T
必须是引用类型(如string
、自定义类等)。 - 注意:引用类型可以为
null
,除非结合where T : notnull
使用(C# 8.0+)。 - 示例:
-
public class Example<T> where T : class { public void PrintType() { Console.WriteLine(typeof(T).Name); } }// 使用示例 var stringExample = new Example<string>(); // 合法 var intExample = new Example<int>(); // 编译错误:int 是值类型
3. where T : new()
- 用途:限制类型参数
T
必须有一个无参公共构造函数。 - 示例:
-
public class Example<T> where T : new() { public T CreateInstance() { return new T(); // 确保可以调用无参构造函数 } }// 使用示例 var example = new Example<List<int>>(); // 合法:List<int> 有无参构造函数 var invalidExample = new Example<StreamReader>(); // 编译错误:StreamReader 没有无参构造函数
4. where T : BaseClass
- 用途:限制类型参数
T
必须继承自指定的基类BaseClass
。 - 示例:
public class BaseClass { } public class DerivedClass : BaseClass { }public class Example<T> where T : BaseClass { public void PrintType() { Console.WriteLine(typeof(T).Name); } }// 使用示例 var validExample = new Example<DerivedClass>(); // 合法 var invalidExample = new Example<string>(); // 编译错误:string 不继承自 BaseClass
5. where T : IInterface
- 用途:限制类型参数
T
必须实现指定的接口IInterface
。 - 示例:
public interface IInterface { void Method(); } public class Implementation : IInterface { public void Method() { } }public class Example<T> where T : IInterface { public void CallMethod(T instance) { instance.Method(); // 确保 T 实现了 IInterface } }// 使用示例 var validExample = new Example<Implementation>(); // 合法 var invalidExample = new Example<string>(); // 编译错误:string 未实现 IInterface
6. where T : U
- 用途:限制类型参数
T
必须是另一个类型参数U
或其派生类型。通常用于泛型类中多个类型参数之间的关系约束。 -
public class BaseClass { } public class DerivedClass : BaseClass { }public class Example<T, U> where T : U { public void PrintTypes() { Console.WriteLine($"T: {typeof(T).Name}, U: {typeof(U).Name}"); } }// 使用示例 var validExample = new Example<DerivedClass, BaseClass>(); // 合法 var invalidExample = new Example<BaseClass, DerivedClass>(); // 编
-