了解如何在 C# 中使用 List<T> 管理数据集合
本介绍性教程介绍了 C# 语言和 List<T> 类的基础知识。
先决条件
本教程要求安装一台虚拟机,以用于本地开发。 请参阅设置本地环境,了解 .NET 的安装说明和应用程序开发概述。
如果希望在不设置本地环境的情况下运行代码,请参阅本教程的交互式浏览器版本。
基本列表示例
创建名为 list-tutorial 的目录。 将新建的目录设为当前目录,并运行 dotnet new console
。
重要
适用于 .NET 6 的 C# 模板使用顶级语句。 如果你已升级到 .NET 6,则应用程序可能与本文中的代码不匹配。 有关详细信息,请参阅有关新 C# 模板生成顶级语句的文章
.NET 6 SDK 还为使用以下 SDK 的项目添加了一组隐式 指令:
- Microsoft.NET.Sdk
- Microsoft.NET.Sdk.Web
- Microsoft.NET.Sdk.Worker
这些隐式 global using
指令包含项目类型最常见的命名空间。
在常用编辑器中,打开 Program.cs,并将现有代码替换为以下代码:
var names = new List<string> { "<name>", "Ana", "Felipe" };
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
将 <name>
替换为自己的名称。 保存 Program.cs。 在控制台窗口中键入 dotnet run
,试运行看看。
你已创建了一个字符串列表,在该列表中添加了三个名称,并打印了所有大写的名称。 循环读取整个列表需要用到在前面的教程中学到的概念。
用于显示名称的代码使用字符串内插功能。 如果 string
前面有 $
符号,可以在字符串声明中嵌入 C# 代码。 实际字符串使用自己生成的值替换该 C# 代码。 在此示例中,{name.ToUpper()}
被替换为各个转换为大写字母的名称,因为调用了 ToUpper 方法。
接下来将进一步探索。
修改列表内容
创建的集合使用 List<T> 类型。 此类型存储一系列元素。 元素类型是在尖括号内指定。
List<T> 类型的一个重要方面是,既可以扩大,也可以收缩,方便用户添加或删除元素。 在程序末尾添加以下代码:
Console.WriteLine();
names.Add("Maria");
names.Add("Bill");
names.Remove("Ana");
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
又向列表的末尾添加了两个名称。 同时,也删除了一个名称。 保存此文件,并键入 dotnet run
,试运行看看。
借助 List<T>,还可以按索引引用各项。 索引位于列表名称后面的 [
和 ]
令牌之间。 C# 对第一个索引使用 0。 将以下代码添加到刚才添加的代码的正下方,并试运行看看:
Console.WriteLine($"My name is {names[0]}");
Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");
不得访问超出列表末尾的索引。 请注意,索引是从 0 开始编制,因此最大有效索引是用列表项数减 1 计算得出。 可以使用 Count 属性确定列表长度。 在程序的末尾添加以下代码:
Console.WriteLine($"The list has {names.Count} people in it");
保存此文件,并再次键入 dotnet run
看看结果如何。
搜索列表并进行排序
我们的示例使用的列表较小,但大家的应用程序创建的列表通常可能会包含更多元素,有时可能会包含数以千计的元素。 若要在更大的集合中查找元素,需要在列表中搜索不同的项。 IndexOf 方法可搜索项,并返回此项的索引。 如果项不在列表中,IndexOf
将返回 -1
。 在程序底部添加以下代码:
var index = names.IndexOf("Felipe");
if (index == -1)
{
Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
Console.WriteLine($"The name {names[index]} is at index {index}");
}
index = names.IndexOf("Not Found");
if (index == -1)
{
Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
Console.WriteLine($"The name {names[index]} is at index {index}");
}
还可以对列表中的项进行排序。 Sort 方法按正常顺序(如果是字符串则按字母顺序)对列表中的所有项进行排序。 在程序底部添加以下代码:
names.Sort();
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
保存此文件,并键入 dotnet run
,试运行此最新版程序。
开始进入下一部分前,先将当前代码移到单独的方法中。 这样一来,可以更轻松地开始处理新示例。 将你编写的所有代码放在一个名为 WorkWithStrings()
的新方法中。 在程序的顶部调用该方法。 完成后,代码应如下所示:
WorkWithString();
void WorkWithString()
{
var names = new List<string> { "<name>", "Ana", "Felipe" };
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
Console.WriteLine();
names.Add("Maria");
names.Add("Bill");
names.Remove("Ana");
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
Console.WriteLine($"My name is {names[0]}");
Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");
Console.WriteLine($"The list has {names.Count} people in it");
var index = names.IndexOf("Felipe");
if (index == -1)
{
Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
Console.WriteLine($"The name {names[index]} is at index {index}");
}
index = names.IndexOf("Not Found");
if (index == -1)
{
Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
Console.WriteLine($"The name {names[index]} is at index {index}");
}
names.Sort();
foreach (var name in names)
{
Console.WriteLine($"Hello {name.ToUpper()}!");
}
}
其他类型的列表
到目前为止,大家一直在列表中使用 string
类型。 接下来,将让 List<T> 使用其他类型。 那就生成一组数字吧。
在调用 WorkWithStrings()
后,在程序中添加以下内容:
var fibonacciNumbers = new List<int> {1, 1};
这会创建一个整数列表,并将头两个整数设置为值 1。 这些是斐波那契数列(一系列数字)的头两个值。 斐波那契数列中的每个数字都是前两个数字之和。 添加以下代码:
var previous = fibonacciNumbers[fibonacciNumbers.Count - 1];
var previous2 = fibonacciNumbers[fibonacciNumbers.Count - 2];
fibonacciNumbers.Add(previous + previous2);
foreach (var item in fibonacciNumbers)
Console.WriteLine(item);
保存此文件,并键入 dotnet run
看看结果如何。
提示
为了能够集中精力探究此部分,可以注释掉调用 WorkingWithStrings();
的代码。 只需在此调用前添加两个 /
字符即可,如 // WorkingWithStrings();
。
挑战
看看能不能将本课程中的一些概念与前面的课程融会贯通。 使用斐波那契数列,扩展当前生成的程序。 试着编写代码,生成此序列中的前 20 个数字。 (作为提示,第 20 个斐波纳契数是 6765。)
完成挑战
可以查看 GitHub 上的完成示例代码,了解示例解决方案。
在循环的每次迭代中,取此列表中的最后两个整数进行求和,并将计算出的总和值添加到列表中。 循环会一直重复运行到列表中有 20 个项为止。
恭喜!已完成“列表集合”教程。 你可以继续在自己的开发环境中学习更多教程。
若要详细了解如何使用 List
类型,可参阅有关集合的 .NET 基础知识文章。 还可以了解其他许多集合类型。