文章目录
- 前言
- 1.什么是集合?
- 2.非泛型集合(了解即可)
- 2.1常见的非泛型集合
- 3.泛型的概念
- 4.常用的泛型集合
- 5. 自定义泛型类和方法
- 5.1 自定义泛型类
- 5.2 自定义泛型方法
前言
C# 中,集合(Collection)是一组有序的数据结构,用于存储和管理一组对象。泛型(Generics)则是 .NET Framework 中一个强大且灵活的功能,它允许我们创建类型安全且高效的集合。本篇文章将详细介绍 C# 中的集合类型、泛型的使用以及如何结合两者高效管理数据。
1.什么是集合?
集合是一组可以存储、管理多个数据的对象容器。集合与数组类似,但集合的容量可以动态调整,不必在声明时指定长度。C# 中的集合分为两种类型:
- 非泛型集合:如 ArrayList、Hashtable,可以存储不同类型的数据,但缺乏类型安全性,需进行频繁的类型转换。
- 泛型集合:如 List、Dictionary<TKey, TValue>,只能存储指定类型的数据,提供了更好的性能和类型安全性。
2.非泛型集合(了解即可)
早期的集合类位于 System.Collections 命名空间中,包括 ArrayList、Hashtable 等。非泛型集合由于可以存储不同类型的数据,灵活性较强,但在存储和取出数据时需进行类型转换,且缺乏编译时类型检查,容易出现类型不匹配的错误。
2.1常见的非泛型集合
- ArrayList:类似数组,但大小可动态调整,存储任何类型的数据。
- Hashtable:键值对的集合,键和值均可为任意类型。
示例:使用 ArrayList 和 Hashtable
using System;
using System.Collections;
class NonGenericCollections
{
static void Main()
{
// ArrayList 示例
ArrayList arrayList = new ArrayList();
arrayList.Add(1);
arrayList.Add("Hello");
arrayList.Add(3.14);
foreach (var item in arrayList)
{
Console.WriteLine(item); // 输出:1, Hello, 3.14
}
// Hashtable 示例
Hashtable hashtable = new Hashtable();
hashtable["name"] = "Alice";
hashtable["age"] = 25;
foreach (DictionaryEntry entry in hashtable)
{
Console.WriteLine($"{entry.Key}: {entry.Value}");
}
}
}
3.泛型的概念
泛型(Generics)允许我们在创建类、接口或方法时定义一个或多个类型参数(通常用 表示),并在使用时指定具体的类型。这种机制在运行时提供类型安全检查,避免了频繁的类型转换。
泛型的优点
- 类型安全:在编译时检查类型一致性,避免类型错误。
- 性能提升:减少装箱(boxing)和拆箱(unboxing),提高效率。
- 可读性和可维护性:代码更清晰、直观,不需要强制类型转换。
4.常用的泛型集合
C# 中常用的泛型集合类位于 System.Collections.Generic 命名空间中。以下是一些常用的泛型集合类:
4.1 List < T > <T> <T>
L i s t < T > List<T> List<T> 是一种动态数组,可根据需要动态调整大小。List 提供了便捷的方法来操作列表中的元素,如添加、删除、排序、搜索等。
using System;
using System.Collections.Generic;
class ListExample
{
static void Main()
{
List<int> numbers = new List<int> { 1, 2, 3 };
numbers.Add(4);
numbers.Remove(2);
foreach (int number in numbers)
{
Console.WriteLine(number); // 输出:1, 3, 4
}
// 检查列表中是否包含某个元素
bool containsThree = numbers.Contains(3); // true
Console.WriteLine("包含3吗?" + containsThree);
}
}
4.2 Dictionary<TKey, TValue>
Dictionary<TKey, TValue> 是一种键值对集合,允许通过键快速访问对应的值。键在字典中是唯一的,但值可以重复。
using System;
using System.Collections.Generic;
class DictionaryExample
{
static void Main()
{
Dictionary<string, int> ages = new Dictionary<string, int>
{
{ "Alice", 25 },
{ "Bob", 30 }
};
ages["Charlie"] = 35;
foreach (var pair in ages)
{
Console.WriteLine($"{pair.Key}: {pair.Value}");
}
// 检查是否存在特定键
if (ages.ContainsKey("Alice"))
{
Console.WriteLine("Alice的年龄是: " + ages["Alice"]);
}
}
}
4.3 Queue < T > <T> <T>
Q u e u e < T > Queue<T> Queue<T> 是一个先进先出(FIFO)的集合。适合用在需要按顺序处理任务的场景,例如任务队列。
using System;
using System.Collections.Generic;
class QueueExample
{
static void Main()
{
Queue<string> queue = new Queue<string>();
queue.Enqueue("Task1");
queue.Enqueue("Task2");
while (queue.Count > 0)
{
string task = queue.Dequeue();
Console.WriteLine("处理: " + task);
}
}
}
4.4 S t a c k < T > Stack<T> Stack<T>
S t a c k < T > Stack<T> Stack<T> 是一个后进先出(LIFO)的集合。适合用于临时存储数据或实现特定算法(如递归)。
using System;
using System.Collections.Generic;
class StackExample
{
static void Main()
{
Stack<string> stack = new Stack<string>();
stack.Push("Page1");
stack.Push("Page2");
while (stack.Count > 0)
{
string page = stack.Pop();
Console.WriteLine("返回: " + page);
}
}
}
4.5 H a s h S e t < T > HashSet<T> HashSet<T>
H a s h S e t < T > HashSet<T> HashSet<T> 是一个无序集合,用于存储唯一值。适合用于需要唯一元素的场景,如不重复数据的集合。
using System;
using System.Collections.Generic;
class HashSetExample
{
static void Main()
{
HashSet<int> set = new HashSet<int> { 1, 2, 3 };
set.Add(3); // 重复添加将被忽略
set.Add(4);
foreach (int item in set)
{
Console.WriteLine(item); // 输出:1, 2, 3, 4
}
}
}
5. 自定义泛型类和方法
5.1 自定义泛型类
可以创建自己的泛型类,使其在不同的数据类型上复用。以下是一个简单的泛型栈实现:
using System;
class GenericStack<T>
{
private T[] elements;
private int index = 0;
public GenericStack(int size)
{
elements = new T[size];
}
public void Push(T item)
{
elements[index++] = item;
}
public T Pop()
{
return elements[--index];
}
}
class Program
{
static void Main()
{
GenericStack<int> stack = new GenericStack<int>(5);
stack.Push(1);
stack.Push(2);
Console.WriteLine(stack.Pop()); // 输出:2
}
}
5.2 自定义泛型方法
泛型方法允许在方法中定义类型参数,使用方式和泛型类类似。以下是一个交换两个变量值的泛型方法示例:
using System;
class Program
{
static void Swap<T>(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
static void Main()
{
int x = 10, y = 20;
Swap(ref x, ref y);
Console.WriteLine($"x = {x}, y = {y}"); // 输出:x = 20, y = 10
}
}