← SEARCHABLE ARCHIVE
C# · 2026-08-02

从 C# 基础到掌握 — 第 6 集

使用集合和 LINQ 操作数据

INTERACTIVE READING MODE →

该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。

游戏和应用程序存储、搜索和排序大量数据。 根据目的选择集合并使用 LINQ 表达处理意图将导致更清晰的流程而不是更短的代码。

选择收藏

var party = new List<Player>();
var itemById = new Dictionary<int, Item>();
var unlockedIds = new HashSet<int>();

itemById.Add(10, new Item(10, "Potion"));
unlockedIds.Add(10);

List适合有序列表,Dictionary适合key查找,HashSet适合判断值是否存在并防止重复。 如果用索引器读取字典中没有的key,就会出现异常,所以可以使用TryGetValue。

使用 LINQ 查询

List<Monster> targets = monsters
    .Where(monster => monster.IsAlive)
    .OrderBy(monster => monster.Health)
    .Take(3)
    .ToList();

选择三个生命值较低的活体怪物的意图从计算顺序中就可见一斑。 LINQ 创建新的结果流,而不自动修改原始集合。

延迟执行

IEnumerable<Monster> alive = monsters.Where(monster => monster.IsAlive);

monsters.Add(new Monster());

foreach (Monster monster in alive)
{
    Console.WriteLine(monster.Health);
}

Where返回的查询通常在遍历时执行。 如果中间原来的改变了,结果也可能会改变。要修复当前结果,请立即使用 ToList() 进行计算。

检查经常性费用

LINQ 调用不一定很慢,但它们可以创建迭代器、委托和结果集合。 对于每帧执行数千次的路径,简单循环和缓冲区重用可能更合适。

targets.Clear();
foreach (Monster monster in monsters)
{
    if (monster.IsAlive)
    {
        targets.Add(monster);
    }
}

最好首先创建一个易于阅读的查询,并仅更改在实际测量中发现问题的部分。 集合和 LINQ 的关键不是拥有最短的语法,而是明确存储数据的目的以及何时处理它。