ZetCode

C# 字典

上次修改日期:2025 年 4 月 23 日

本教程探讨了 C# 字典集合,演示了其创建、操作和实际应用。

C# 字典

字典通常被称为关联数组,它存储映射到特定值的唯一键,从而实现快速数据检索和插入。 虽然对于查找非常有效,但由于存储键和值,字典会消耗额外的内存。

C# 字典初始化器

C# 字典可以使用简洁的字面量表示法进行初始化,在声明期间,键值对在花括号 {} 中定义。

Program.cs
var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

Console.WriteLine(domains["sk"]);

var days = new Dictionary<string, string>
{
    ["mo"] =  "Monday",
    ["tu"] =  "Tuesday",
    ["we"] =  "Wednesday",
    ["th"] =  "Thursday",
    ["fr"] =  "Friday",
    ["sa"] =  "Saturday",
    ["su"] =  "Sunday"
};

Console.WriteLine(days["fr"]);

此示例创建了两个使用不同初始化器语法的字典,用于存储国家/地区代码和星期几。

var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

此代码使用字符串键和值初始化一个字典。尖括号 <> 定义了键和值的数据类型。 键值对包含在嵌套的 {} 中,用逗号分隔,将每个键(例如 "sk")链接到其值(例如 "Slovakia")。

Console.WriteLine(domains["sk"]);

要检索值,请使用字典的名称,后跟方括号 [] 中的键,这将返回关联的值。

var days = new Dictionary<string, string>
{
    ["mo"] =  "Monday",
    ["tu"] =  "Tuesday",
    ["we"] =  "Wednesday",
    ["th"] =  "Thursday",
    ["fr"] =  "Friday",
    ["sa"] =  "Saturday",
    ["su"] =  "Sunday"
};

这种替代的初始化器语法使用索引表示法将值分配给键,提供了一种清晰而灵活的方式来填充字典。

$ dotnet run
Slovakia
Friday

C# 字典计数元素

Count 属性返回字典中键值对的总数,提供了一种快速评估其大小的方法。

Program.cs
var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

domains.Add("pl", "Poland");

Console.WriteLine($"There are {domains.Count} items in the dictionary");

此示例演示了在添加新的键值对后,计算字典中条目的数量。

Console.WriteLine($"There are {domains.Count} items in the dictionary");

此语句使用 Count 属性显示字典中键值对的数量。

$ dotnet run
There are 5 items in the dictionary

C# 字典添加、删除元素

字典是动态的,允许在其初始创建后添加或删除键值对,以适应不断变化的数据需求。

Program.cs
var users = new Dictionary<string, int>()
{
    { "John Doe", 41 },
    { "Jane Doe", 38 },
    { "Lucy Brown", 29 },
};

users["Paul Brown"] = 33;
users.Add("Thomas Pattison", 34);

Console.WriteLine(string.Join(", ", users));

users.Remove("Jane Doe");

Console.WriteLine(string.Join(", ", users));

users.Clear();

if (users.Count == 0)
{
    Console.WriteLine("The users dictionary is empty");
}

此示例创建一个字典,并通过使用内置方法添加、删除和清除条目来对其进行修改。

var users = new Dictionary<string, int>()
{
    { "John Doe", 41 },
    { "Jane Doe", 38 },
    { "Lucy Brown", 29 },
};

这会使用字符串键(名称)和整数值(年龄)初始化一个字典,从而设置初始数据集。

users["Paul Brown"] = 33;
users.Add("Thomas Pattison", 34);

使用索引表示法和 Add 方法添加了两个新的键值对,从而扩展了字典。

Console.WriteLine(string.Join(", ", users));

Join 方法将所有键值对连接成一个字符串,以便于显示。

users.Remove("Jane Doe");

Remove 方法通过指定键(在本例中为 "Jane Doe")来删除键值对。

users.Clear();

Clear 方法删除所有键值对,从而清空字典。

$ dotnet run
[John Doe, 41], [Jane Doe, 38], [Lucy Brown, 29], [Paul Brown, 33], [Thomas Pattison, 34]
[John Doe, 41], [Lucy Brown, 29], [Paul Brown, 33], [Thomas Pattison, 34]
The users dictionary is empty

C# 字典 ContainsKey 和 ContainsValue 方法

ContainsKey 方法检查字典中是否存在特定键,而 ContainsValue 验证特定值的存在,有助于数据验证。

Program.cs
var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

var key = "sk";

if (domains.ContainsKey(key))
{
    Console.WriteLine($"The {key} key is in the dictionary");
} else
{
    Console.WriteLine($"The {key} key is in not the dictionary");
}

var value = "Slovakia";

if (domains.ContainsValue(value))
{
    Console.WriteLine($"The {value} value is in the dictionary");
} else
{
    Console.WriteLine($"The {value} value is in not the dictionary");
}

此示例使用 ContainsKeyContainsValue 测试字典中是否存在特定键和值。

$ dotnet run
The sk key is in the dictionary
The Slovakia value is in the dictionary

C# 遍历字典

C# 提供了多种迭代字典的方法,允许灵活访问其键值对以进行处理或显示。

Program.cs
var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

foreach (var (key, value) in domains)
{
    Console.WriteLine($"{key}: {value}");
}

Console.WriteLine("**************************************");

foreach (var kvp in domains)
{
    Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}

Console.WriteLine("**************************************");

// oldschool
foreach (KeyValuePair<string, string> entry in domains)
{
    Console.WriteLine($"{entry.Key}: {entry.Value}");
}

此示例演示了使用 foreach 循环迭代字典的三种方法,每种方法以不同的方式访问键值对。

foreach (var (key, value) in domains)
{
    Console.WriteLine($"{key}: {value}");
}

这种现代语法将每个键值对解构为单独的变量,以便在迭代期间直接访问。

foreach (var kvp in domains)
{
    Console.WriteLine($"{kvp.Key}: {kvp.Value}");
}

这种方法使用每个键值对的 KeyValue 属性来访问数据。

// oldschool
foreach (KeyValuePair<string, string> entry in domains)
{
    Console.WriteLine($"{entry.Key}: {entry.Value}");
}

这种传统方法使用 KeyValuePair 进行迭代,显式定义键值对结构以与旧代码兼容。

$ dotnet run
sk: Slovakia
ru: Russia
de: Germany
no: Norway
**************************************
sk: Slovakia
ru: Russia
de: Germany
no: Norway
**************************************
sk: Slovakia
ru: Russia
de: Germany
no: Norway

C# 还支持对键或值进行单独迭代,从而可以有针对性地访问字典的任一组件。

Program.cs
var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

Console.WriteLine("Keys:");

foreach (var val in domains.Keys)
{
    Console.WriteLine(val);
}

Console.WriteLine("\nValues:");

foreach (var val in domains.Values)
{
    Console.WriteLine(val);
}

此示例使用两个 foreach 循环分别迭代字典的键和值,以便进行集中的数据提取。

foreach (var val in domains.Keys)
{
    Console.WriteLine(val);
}

Keys 属性提供对字典中所有键的访问,这对于特定于键的操作非常有用。

foreach (var val in domains.Values)
{
    Console.WriteLine(val);
}

Values 属性检索所有值,从而可以进行以值为中心的处理,而无需键。

$ dotnet run
Keys:
sk
ru
de
no

Values:
Slovakia
Russia
Germany
Norway

C# 排序字典

使用 LINQ,可以按键或值对字典进行排序,从而可以有组织地显示数据以进行分析或显示。

Program.cs
var users = new Dictionary<string, int>()
{
    { "John", 41 },
    { "Jane", 38 },
    { "Lucy", 29 },
    { "Paul", 24 }
};

var sortedUsersByValue = users.OrderBy(user => user.Value);

foreach (var user in sortedUsersByValue)
{
    Console.WriteLine($"{user.Key} is {user.Value} years old");
}

此示例使用 LINQ 按其值(年龄)对字典进行排序,以年龄升序显示用户。

var sortedUsersByValue = users.OrderBy(user => user.Value);

OrderBy 方法根据字典条目的值对其进行排序,从而创建一个有序序列。

$ dotnet run
Paul is 24 years old
Lucy is 29 years old
Jane is 38 years old
John is 41 years old

C# SortedDictionary

SortedDictionary 类维护按键排序的键值对,确保自动排序以实现高效的数据访问。

Program.cs
var sortedUsers = new SortedDictionary<string, int>()
{
    { "John", 41 },
    { "Jane", 38 },
    { "Lucy", 29 },
    { "Paul", 24 }
};

foreach (var user in sortedUsers)
{
    Console.WriteLine($"{user.Key} is {user.Value} years old");
}

此示例展示了 SortedDictionary,它自动按键对条目进行排序,以获得一致的输出。

$ dotnet run
Jane is 38 years old
John is 41 years old
Lucy is 29 years old
Paul is 24 years old

C# 列表字典

字典可以存储复杂的数据(例如列表)作为值,从而可以对嵌套数据集合进行结构化组织。

Program.cs
var data = new Dictionary<int, List<int>>();

var vals1 = new List<int> { 1, 1, 1, 1, 1 };
var vals2 = new List<int> { 3, 3, 3, 3, 3 };
var vals3 = new List<int> { 5, 5, 5, 5, 5 };

data.Add(1, vals1);
data.Add(2, vals2);
data.Add(3, vals3);

var TotalSum = 0;

foreach (var (key, e) in data)
{
    var _sum = e.Sum();
    TotalSum += _sum;
    Console.WriteLine($"The sum of nested list is: {_sum}");
}

Console.WriteLine($"The total sum is: {TotalSum}");

此示例创建一个以列表作为值的字典,计算每个列表的总和,并计算总和。

$ dotnet run
The sum of nested list is: 5
The sum of nested list is: 15
The sum of nested list is: 25
The total sum is: 45

C# 字典 TryGetValue 方法

TryGetValue 方法安全地检索给定键的值,避免在找不到键时出现异常,从而增强了健壮性。

Program.cs
var domains = new Dictionary<string, string>
{
    {"sk", "Slovakia"},
    {"ru", "Russia"},
    {"de", "Germany"},
    {"no", "Norway"}
};

string key = "fr";
if (domains.TryGetValue(key, out string? value))
{
    Console.WriteLine($"Found {key}: {value}");
}
else
{
    Console.WriteLine($"Key {key} not found in the dictionary");
}

key = "sk";
if (domains.TryGetValue(key, out value))
{
    Console.WriteLine($"Found {key}: {value}");
}
else
{
    Console.WriteLine($"Key {key} not found in the dictionary");
}

此示例使用 TryGetValue 尝试检索现有和非现有键的值,并优雅地处理这两种情况。

$ dotnet run
Key fr not found in the dictionary
Found sk: Slovakia

C# 字典键不区分大小写

使用 StringComparer,可以使字典的键不区分大小写,从而简化了区分大小写情况下的查找。

Program.cs
var domains = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
    {"SK", "Slovakia"},
    {"RU", "Russia"},
    {"DE", "Germany"}
};

Console.WriteLine(domains["sk"]);
Console.WriteLine(domains["RU"]);

此示例创建一个不区分大小写的字典,允许进行不区分大小写的键查找,并检索混合大小写键的值。

$ dotnet run
Slovakia
Russia

来源

字典类 - 语言参考

本教程全面探讨了 C# 字典集合,涵盖了其创建、操作和高级用例。

作者

我是 Jan Bodnar,是一位经验丰富的软件开发程序员。 自 2007 年以来,我撰写了超过 1,400 篇编程文章和八本电子书。 凭借十多年的教学经验,我通过全面而实用的教程分享我的知识。

列出所有 C# 教程