|
主题设置

卡片式面板通常用于非白色背景色的主体内

泛型

在 C# 中,泛型允许定义类、接口、方法等的类型参数,以便在编译时提供类型安全而不需要运行时转换。

泛型优点

  • 类型安全: 避免了运行时类型错误,通过编译时检查确保类型一致性。
  • 代码重用: 通过定义一个通用的类型或方法,可以重用代码,而不需要为每种数据类型编写多个实现。
  • 性能: 避免了装箱(boxing)和拆箱(unboxing)操作,提高了性能。

泛型类

定义一个泛型类 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 删除

foreach(var stu in stuList){
	if(stu.name = "Tange"){
		stuList.Remove(stu);
	}
}

会报如下错误:

因为在 foreach 中删除元素时,每一次删除都会导致集合的大小和元素索引值发生变化,从而导致在 foreach 中删除元素会出现异常。

for 正序删除

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 倒序删除

for(int i=stuList.Count-1; i>=0; i--){
	if(stuList[i].name == "Tang"){
		stuList.Remove(stuList[i]);
	}
}

结果:

这是删除了全部姓名为 Tang 的学生。