1. 泛型类 (GenericContainer<T>
)
-
这是一个可以存储任何类型数据的容器类
-
使用类型参数
T
表示存储的数据类型 -
同一个类可以用于创建存储不同类型数据的容器
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
public class GenericContainer<T>
{
private T _myvalue;
/// <summary>
/// 赋值
/// </summary>
/// <param name="myvalue"></param>
public void funcon(T myvalue)
{
_myvalue = myvalue;
}
/// <summary>
/// 取出泛型对应的值
/// </summary>
/// <returns></returns>
public T TakeOut()
{
return _myvalue;
}
}
}
2、辅助类
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
/// <summary>
/// 辅助类
/// </summary>
public class mygenicaa
{
public string xName { get; set; }
public int xAge { get; set; }
public mygenicaa(string XName, int XAge)
{
xName = XName;
xAge = XAge;
}
/// <summary>
/// 辅助类函数,输出辅助类参数
/// </summary>
public void fuc()
{
Console.WriteLine(xName);
}
}
}
3、主函数
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class MagicBox<T>
{
private T _content; // T 代表未知类型
// 把东西放进盒子
public void PutIn(T item)
{
_content = item;
}
// 从盒子取出东西
public T TakeOut()
{
return _content;
}
}
// 辅助类
class Person
{
public string Name { get; }
public int Age { get; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
internal class Program
{
static void Main(string[] args)
{
// 1. 装整数的盒子
MagicBox<int> numberBox = new MagicBox<int>();
numberBox.PutIn(100);
int number = numberBox.TakeOut();
Console.WriteLine($"取出数字: {number}");
// 2. 装字符串的盒子
MagicBox<string> textBox = new MagicBox<string>();
textBox.PutIn("Hello 泛型!");
string text = textBox.TakeOut();
Console.WriteLine($"取出文本: {text}");
// 3. 装自定义对象的盒子
MagicBox<Person> personBox = new MagicBox<Person>();
personBox.PutIn(new Person("小明", 20));
Person person = personBox.TakeOut();
Console.WriteLine($"取出人物: {person.Name}, {person.Age}岁");
GenericContainer<string> myGeric = new GenericContainer<string>();
//打印一个字符串
myGeric.funcon("hhaa");
string ss= myGeric.TakeOut();
//自定义的对象用于泛型
GenericContainer<mygenicaa> mygeric2 = new GenericContainer<mygenicaa>();
mygeric2.funcon(new mygenicaa("hh",32));
mygenicaa myge = mygeric2.TakeOut();
Console.WriteLine($"取出人物: {myge.xName}, {myge.xAge}岁");
Console.ReadKey();
}
}
}
泛型是 C# 和 .NET 框架中一个非常重要的特性,它允许你编写可以处理任何数据类型的类、方法、接口和委托,而无需在编写代码时指定具体的数据类型。
1.1 泛型类型参数
使用 <T>
定义类型参数,T
是约定俗成的名称(表示 Type),你也可以使用其他名称
cs
public class GenericList<T>
{
public void Add(T input) { }
}
1.2 类型参数命名约定
-
T
: 单一类型参数 -
TKey
,TValue
: 多个类型参数时使用描述性名称 -
TResult
: 表示返回值的类型参数
2. 泛型类型
2.1 泛型类
cs
// 泛型类
public class GenericClass<T>
{
private T data;
public GenericClass(T data)
{
this.data = data;
}
public T GetData()
{
return data;
}
}
// 使用
GenericClass<int> intObj = new GenericClass<int>(100);
GenericClass<string> stringObj = new GenericClass<string>("Hello");
2.2 泛型接口
cs
// 泛型接口
public interface IRepository<T>
{
void Add(T item);
T GetById(int id);
}
// 实现泛型接口
public class ProductRepository : IRepository<Product>
{
public void Add(Product item) { /* 实现 */ }
public Product GetById(int id) { /* 实现 */ }
}
2.3 泛型委托
cs
// 泛型委托
public delegate TOutput Converter<TInput, TOutput>(TInput input);
// 使用
Converter<string, int> converter = int.Parse;
int result = converter("123");
- 泛型方法
cs
public class Utility
{
// 泛型方法
public static void Swap<T>(ref T lhs, ref T rhs)
{
T temp = lhs;
lhs = rhs;
rhs = temp;
}
// 泛型返回类型
public static T GetDefault<T>()
{
return default(T);
}
}
// 使用
int a = 1, b = 2;
Utility.Swap(ref a, ref b);
4. 类型约束
为了限制可以使用的类型参数,可以使用约束:
4.1 常用约束类型
public class GenericClass<T> where T : constraint
{
// ...
}

4.2 约束示例
cs
public class GenericClass<T> where T : IComparable, new()
{
public T CreateInstance()
{
return new T(); // 需要 new() 约束
}
public int Compare(T a, T b)
{
return a.CompareTo(b); // 需要 IComparable 约束
}
}
6. 泛型中的默认值
使用 default
关键字获取类型参数的默认值:
cs
public T GetDefaultValue()
{
return default(T);
// 对于引用类型返回 null
// 对于值类型返回 0/false 等
}
7. 泛型集合
.NET 提供了许多内置的泛型集合类:
cs
// 常用泛型集合
List<T> // 动态数组
Dictionary<TKey, TValue> // 字典
Queue<T> // 队列
Stack<T> // 栈
HashSet<T> // 集合
9. 最佳实践
-
使用描述性的类型参数名:当有多个类型参数时
-
尽可能使用约束:增加类型安全性
-
考虑性能:泛型避免装箱拆箱,提高性能
-
利用代码复用:避免为不同类型编写相似代码
10. 总结
泛型是 C# 中强大的特性,它提供了:
-
类型安全:编译时类型检查
-
性能提升:避免装箱拆箱
-
代码复用:一套代码处理多种类型
-
可读性:代码意图更明确
通过掌握泛型,你可以编写更加灵活、安全和高效的 C# 代码。