C#之泛型🔥
# 什么是泛型
在C#中,泛型是一种强大的特性,它允许您编写可以在不同类型上进行参数化的代码。通俗地说,泛型允许您编写可以在不同类型(例如整数、字符串、自定义对象等)上执行相同逻辑的代码,而不必为每种类型编写不同的代码。这使得您的代码更具通用性和可重用性。通过泛型,您可以定义类、接口、方法和委托,这些可以接受类型参数,从而使其在编译时具有更高的类型安全性。使用泛型可以在编译时捕获类型错误,而不是在运行时。例如,您可以创建一个泛型类来存储任何类型的数据,而不是仅限于一种特定类型。这样的类在使用时可以根据需要指定所需的类型,从而增加了灵活性和可扩展性。
# 1、泛型类
public class GenericList<T>
{
private T[] list;
private int count;
public GenericList(int capacity)
{
list = new T[capacity];
count = 0;
}
public void Add(T item)
{
if (count < list.Length)
{
list[count] = item;
count++;
}
}
public T GetItem(int index)
{
if (index >= 0 && index < count)
{
return list[index];
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
使用泛型类:
GenericList<int> intList = new GenericList<int>(5);
intList.Add(10);
intList.Add(20);
int item = intList.GetItem(0);
2
3
4
# 2、泛型方法
public class Utility
{
public static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
}
2
3
4
5
6
7
8
9
使用泛型方法:
int x = 10;
int y = 20;
Utility.Swap(ref x, ref y);
2
3
# 3、泛型接口
public interface IRepository<T>
{
void Add(T item);
T GetById(int id);
IEnumerable<T> GetAll();
}
2
3
4
5
6
使用泛型接口:
// 实现泛型接口的具体类
public class UserRepository : IRepository<User>
{
private List<User> users = new List<User>();
public void Add(User user)
{
users.Add(user);
}
public User GetById(int id)
{
return users.Find(u => u.Id == id);
}
public IEnumerable<User> GetAll()
{
return users;
}
}
// 泛型类
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
// 使用 UserRepository 实例
var userRepository = new UserRepository();
userRepository.Add(new User { Id = 1, Name = "Alice" });
userRepository.Add(new User { Id = 2, Name = "Bob" });
// 获取用户
User user = userRepository.GetById(1);
Console.WriteLine($"User with Id 1: {user.Name}");
// 获取所有用户
IEnumerable<User> allUsers = userRepository.GetAll();
Console.WriteLine("All Users:");
foreach (var u in allUsers)
{
Console.WriteLine($"Id: {u.Id}, Name: {u.Name}");
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
在上面的示例中,UserRepository 类实现了这个泛型接口,但只适用于 User 类型。这样,您可以轻松地为不同类型的数据创建具有相同接口的存储库实现,从而提高了代码的灵活性和可维护性。
# 4、泛型委托
public delegate void ProcessData<T>(T data);
public class Processor
{
public static void PrintData<T>(T data)
{
Console.WriteLine(data);
}
}
2
3
4
5
6
7
8
9
使用泛型委托:
ProcessData<int> processInt = Processor.PrintData;
processInt(10);
2
# 泛型约束
在C#中,泛型约束用于限制可以用作泛型类型参数的类型。通过约束,您可以为泛型类型参数指定必须满足的条件,从而增强代码的类型安全性和可读性。以下是一些常见的泛型约束:
1、where T : class:指定类型参数必须是引用类型(类)。
2、where T : struct:指定类型参数必须是值类型(结构体),这个约束使得类型参数不能是类。
3、where T : new():指定类型参数必须具有无参数的公共构造函数。
4、where T : <基类名>:指定类型参数必须是指定基类或其派生类。
5、where T : <接口名>:指定类型参数必须实现指定的接口。
这些约束可以单独使用,也可以结合在一起使用,以满足特定的需求。例如,您可以同时使用 class 和 new() 约束来确保类型参数是引用类型并且具有无参数的公共构造函数。使用泛型约束可以让您编写更安全、更清晰的泛型代码,并减少运行时错误的可能性。