在 C# 中,泛型允许定义类、接口、方法等的类型参数,以便在编译时提供类型安全而不需要运行时转换。
定义一个泛型类 List<T>:
public class List<T>
{
private T[] items;
public void Add(T item) { /*...*/ }
public T Get(int index) { /*...*/ }
}
可以创建 List<int> 和 List<string> 的实例,这样 T 就分别被替换为 int 和 string。
定义一个 int 型的泛型集合:
List<int> list_1 = new List<int>();
// 往泛型集合里面添加数据
list_1.Add(3);
list_1.Add(4);
// 遍历泛型集合
foreach(int i in list_1)
{
Console.WriteLine(i);
}
定义一个 Student 类的泛型集合
// 先定义一个学生类
class Student
{
public string name{get;set;}
public int age{get;set;}
public void show
{
Console.WriteLine("学生姓名:" + name + ",年龄:" + age);
}
}
// 用学生类定义泛型
List<Student> list_2 = new List<Student>();
// 实例化两个学生类,并给相关属性赋值
Student stu1 = new Student();
stu1.name = "李白";
stu1.age = 56;
Student stu2 = new Student();
stu2.name = "杜甫";
stu2.age = 46;
list_2.Add(stu1);
list_2.Add(stu2);
// 求学生的年龄总和
int sum = 0;
foreach(Student stu in list_2)
{
sum += str.age;
}
Console.WriteLine(sum);
// 往泛型集合里面添加数据
list_2.Add(stu1);
// 往泛型集合里面插入内容
// 0 表示插入的位置(在索引为 0 的地方),stu3 表示插入的内容,这样一来 stu3 就在先 Add 进去的 stu1 的前面了
list_2.Insert(0,stu3);
// 从泛型集合里根据删除指定元素
list_2.Remove(stu1);
// 从泛型集合里根据索引删除内容
list_2.RemoveAt(0); // 删掉了在索引 0 位置的内容
// 清空泛型集合
list_2.Clear();
删除 List<T> 中的元素时,不能使用 foreach 循环删除,也不能使用 for 循环的正序删除。
有例子如下:
class Program{
public class Student
{
public string name{get;set;}
public int age{get;set;}
public Student(string _name,int _age)
{
this.name = _name;
this.age = _age;
}
}
static void Main(string[] args){
List<Student> stuList = new List<Student>();
stuList.Add(new Student("Tom",20));
stuList.Add(new Student("Tang",20));
stuList.Add(new Student("Tang",20));
stuList.Add(new Student("Trista",20));
stuList.Add(new Student("Lili",20));
}
// 打印姓名
Console.Write("删除前:");
foreach(var stu in stuList){
Console.Write(stu.name + " ");
}
Console.ReadKey();
}
打印结果:删除前:zhangsan lisi lisi wangwu mazi
foreach(var stu in stuList){
if(stu.name = "Tange"){
stuList.Remove(stu);
}
}
会报如下错误:
因为在 foreach 中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,从而导致在 foreach 中删除元素会出现异常。
Console.Write("删除前:");
foreach(var stu in stuList){
Console.Write(stu.name + " ");
}
// 删除姓名为 Tang 的学生
for(int i=0; i<stuList.Count; i++){
if(stuList[i].Name == "Tang"){
stuList.Remove(stuList[i]);
}
}
// 打印姓名
Console.Write("\n删除后");
foreach(var stu in stuList){
Console.Write(stu.Name + " ");
}
结果:
只删除了一个姓名为 Tang 的学生,为什么会出现这样的情况呢?
这是因为当 i = 1 时,满足条件执行删除操作,会移除一个 Tang,接着第二个 Tang 会前移到第一个 Tang 的位置,即游标 1 对应的是第二个 Tang。
接着遍历 i = 2,也就跳过第二个 Tang。
for(int i=stuList.Count-1; i>=0; i--){
if(stuList[i].name == "Tang"){
stuList.Remove(stuList[i]);
}
}
结果:
这是删除了全部姓名为 Tang 的学生。