0Pricing
C# Academy · 课时

实践中的列表

添加、移除和搜索。

实践中的列表 是 CoddyKit 上的免费 C# Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C# Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C# Academy 课程共包含 4 节课。

为什么使用 List<T>

List<T> 是 C# 中日常使用的动态数组。它位于 System.Collections.Generic 中,并会在添加项目时自动扩容。

与普通数组不同,您不必预先设置固定大小。它还是类型安全的:List<int> 只能保存 int 值,并且会在编译时发现类型错误。

using System.Collections.Generic;

List<int> scores = new List<int>();
scores.Add(90);
scores.Add(85);

创建和初始化

您可以使用集合初始化器立即填充列表。这种写法简洁易读。

编译器会在幕后将每个条目转换为一次 Add 调用,因此结果与逐个添加项目完全相同。

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var fruits = new List<string> { "apple", "pear", "plum" };
        Console.WriteLine(fruits.Count);
    }
}

索引与 Count

您可以像访问数组一样,通过从零开始的索引访问元素。list[0] 是第一个项目。

请使用 Count(而不是 Length)获取列表中包含多少个项目。通过索引读取或写入的时间复杂度为 O(1),也就是常数时间。

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var nums = new List<int> { 10, 20, 30 };
        Console.WriteLine(nums[1]);
        Console.WriteLine(nums.Count);
    }
}

添加与插入

Add 会以摊销 O(1) 的时间复杂度追加到末尾。AddRange 可以一次追加多个项目。

Insert(index, item) 会将项目放到指定位置,并移动其后的所有项目。由于这种移动,从开头执行 Insert 的时间复杂度为 O(n),因此可以在末尾添加时,优先选择这种方式。

var list = new List<string> { "b", "c" };
list.Insert(0, "a");
list.AddRange(new[] { "d", "e" });
// list is now a, b, c, d, e

移除项目

Remove(item) 会删除第一个匹配的值,并在找到该值时返回 true。RemoveAt(index) 会根据位置删除项目。

这两种操作都会将后续元素向左移动,因此从中间删除的时间复杂度为 O(n)。RemoveAll 接受一个谓词,并在一次遍历中删除所有匹配项。

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var nums = new List<int> { 1, 2, 3, 4, 5 };
        nums.RemoveAll(n => n % 2 == 0);
        Console.WriteLine(string.Join(",", nums));
    }
}

搜索列表

Contains 会告诉您某个值是否存在;IndexOf 会返回它的位置,如果不存在则返回 -1。两者都会进行线性扫描,时间复杂度为 O(n)。

如果您发现自己需要反复按值搜索一个大型列表,这种线性开销会不断累积。此时,HashSet 或 Dictionary 可能更合适。

var names = new List<string> { "Ann", "Bob", "Cy" };
bool hasBob = names.Contains("Bob");   // true
int pos = names.IndexOf("Cy");          // 2

遍历

foreach 循环是读取每个元素最清晰的方式。如果需要索引,也可以使用经典的 for 循环。

不要在遍历同一个列表的 foreach 中添加或删除项目,否则会抛出 InvalidOperationException。

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var colors = new List<string> { "red", "green", "blue" };
        foreach (var c in colors)
            Console.WriteLine(c);
    }
}

排序

Sort() 会使用默认比较器直接对列表进行排序。要使用自定义顺序,请传入比较委托。

排序的时间复杂度为 O(n log n)。如果希望获得排序后的副本而不改变原始列表,请使用 LINQ 的 OrderBy,它会返回一个新序列。

using System;
using System.Collections.Generic;

class Program {
    static void Main() {
        var nums = new List<int> { 4, 1, 3, 2 };
        nums.Sort();
        Console.WriteLine(string.Join(",", nums));
    }
}

Capacity 与 Count

Count 表示当前存在多少个项目;Capacity 表示在重新分配内部数组之前可以容纳多少个项目。

当列表增长到超过容量时,它会分配一个更大的数组并复制项目,容量大致会翻倍。如果您知道最终大小,可以在构造函数中传入该大小,以避免反复复制。

var list = new List<int>(1000); // reserve capacity
for (int i = 0; i < 1000; i++)
    list.Add(i);
// no intermediate reallocations

将列表作为方法参数

List<T> 是引用类型。将它传递给方法时,传递的是引用,因此方法内部的更改会影响调用方的列表。

如果方法只读取数据,请接受 IEnumerable<T> 或 IReadOnlyList<T>,以表明您不会修改它。

using System;
using System.Collections.Generic;

class Program {
    static void AddOne(List<int> xs) => xs.Add(1);
    static void Main() {
        var nums = new List<int>();
        AddOne(nums);
        Console.WriteLine(nums.Count); // 1
    }
}

转换与复制

ToArray() 会生成固定大小的数组;new List<T>(other) 会创建另一个序列的浅复制。

浅复制会复制列表结构,但共享相同的元素引用,因此修改其中包含的对象时,通过两个列表都能看到这一变化。

var original = new List<int> { 1, 2, 3 };
int[] arr = original.ToArray();
var copy = new List<int>(original);

快速检查

请选择开销最突出的操作。

回顾

List<T> 是一种可扩容且类型安全的数组。索引访问和 Count 的时间复杂度为 O(1);在末尾使用 Add 的摊销时间复杂度为 O(1)。

在中间插入、删除以及按值搜索的时间复杂度为 O(n),因为这些操作需要移动或扫描。已知大小时请预留容量,以避免重新分配。

常见问题解答

「实践中的列表」课时是免费的吗?

是的 — 「实践中的列表」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C# Academy 课程的其余内容,请升级到 CoddyKit PRO。 C# Academy 课程共包含 4 节课。

「实践中的列表」这节课中我会学到什么?

添加、移除和搜索。 你通过在浏览器中直接运行的动手代码来练习 C# Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C# Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C# Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「实践中的列表」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C# Academy 课中编写并运行代码吗?

能。每节 C# Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 实践中的列表
  2. 字典查找
  3. HashSet 与唯一性
  4. 选择集合
← 返回 C# Academy