本教程是C#的入门学习教程,我尽量找时间写全它,预计每周不少于3篇吧,但由于不是专业搞课程的,只能是尽力而为,希望对你入门有所帮助。
在 C# 开发中,Dictionary<TKey, TValue>
(简称 Dictionary)是一种非常常用且高效的数据结构。它也可以帮助我们快速访问、管理大量的键值对。在本文中,我们将结合示例详细介绍 Dictionary 的使用场景、常用操作以及最佳实践,帮助你更好地理解 C# 字典在实际业务中的运用。如果你了解JSON就对它了解了,可以说,这个是现在NOSQL的根了。
什么是 C# Dictionary
Dictionary<TKey, TValue>
是 C# 基础类库中提供的泛型集合类型,用于存储键值对(Key-Value pair)。
- Key(键)
:具有唯一性,如果插入重复键,会抛出异常或覆盖视具体情况而定。 - Value(值)
:可以重复,不限制唯一性。
Dictionary 的特点
快速查找
Dictionary 使用哈希表(Hash Table)实现,能提供平均 O(1) 的查找速度,也就是说,随着元素数量的增多,其访问效率依然较为稳定和高效。
无序集合
Dictionary 中元素存储顺序并不一定与插入顺序一致,无法按照加入的顺序来遍历获取,需要注意这一点。
泛型支持
Dictionary<TKey, TValue>
支持指定键和值的数据类型,能更好地利用类型安全。应用场景广
- 缓存系统的存储:根据唯一标识(Key)快速检索对象。
- 数据统计:用键来表示一个标识或名称,值用于存储统计结果或其他信息。
- 快速查找表:需要在海量数据中快速定位时,非常适用。
- 配置管理:常用来加载配置项,按键快速检索。
Dictionary 常用操作
以下为 Dictionary 中常见的方法和属性:
Add(TKey key, TValue value)
添加新的键值对。若键已存在,会抛出异常。
Remove(TKey key)
根据键删除对应的键值对。
ContainsKey(TKey key)
判断字典中是否包含指定键。
ContainsValue(TValue value)
判断字典中是否包含指定值。
TryGetValue(TKey key, out TValue value)
尝试获取与指定键关联的值,避免在键不存在时发生异常。
this[TKey key](索引器)
获取或设置与指定键相关联的值。但若键不存在,直接访问会抛出异常,因此推荐配合
TryGetValue()
使用。
示例:添加、访问和删除操作
using System;
using System.Collections.Generic;
namespace AppDictionary
{
internal class Program
{
static void Main(string[] args)
{
// 1. 创建一个 Dictionary,键为 string,值为 int
Dictionary<string, int> ages = new Dictionary<string, int>();
// 2. 使用 Add 方法添加键值对
ages.Add("Alice", 30);
ages.Add("Bob", 25);
// 3. 通过索引器方式添加或修改数据
ages["Charlie"] = 28;
// 4. 遍历字典中的所有键值对
foreach (KeyValuePair<string, int> kvp in ages)
{
Console.WriteLine($"Name: {kvp.Key}, Age: {kvp.Value}");
}
// 5. 检查字典中是否包含某个键
if (ages.ContainsKey("Alice"))
{
Console.WriteLine("找到 Alice,Age = " + ages["Alice"]);
}
// 6. 使用 TryGetValue 方法安全地获取值
if (ages.TryGetValue("Bob", out int bobAge))
{
Console.WriteLine("找到 Bob,Age = " + bobAge);
}
// 7. 使用 Remove 方法移除键值对
ages.Remove("Charlie");
// 移除后再次检查
if (!ages.ContainsKey("Charlie"))
{
Console.WriteLine("Charlie 已从字典中移除");
}
}
}
}复制

结合 LINQ 的 Dictionary 查询示例
在 C# 中,结合 LINQ(Language Integrated Query)可以更灵活地对 Dictionary 进行查询和操作。下面示例展示了如何在字典里使用 LINQ 筛选出符合条件的项目,并倒序排列它们的值。
using System;
using System.Collections.Generic;
using System.Linq;
namespace AppDictionary
{
internal class Program
{
static void Main(string[] args)
{
// Dictionary 初始化
Dictionary<string, int> scores = new Dictionary<string, int>()
{
{"Alice", 95},
{"Bob", 80},
{"Charlie", 85},
{"David", 90}
};
// 查找分数大于 85 的学生,并按照分数倒序
var highScores = scores.Where(kvp => kvp.Value > 85)
.OrderByDescending(kvp => kvp.Value);
Console.WriteLine("High Scores:");
foreach (var score in highScores)
{
Console.WriteLine($"{score.Key}: {score.Value}");
}
// 转换为新的映射关系:成绩转化为 A、B、C
Dictionary<string, string> gradeMap =
scores.ToDictionary(
kvp => kvp.Key,
kvp => kvp.Value >= 90 ? "A" : kvp.Value >= 80 ? "B" : "C"
);
Console.WriteLine("Grade Map:");
foreach (var item in gradeMap)
{
Console.WriteLine($"{item.Key}: {item.Value}");
}
}
}
}复制

在实际开发中,配合 LINQ 能够大幅度提高数据处理的可读性和开发效率,无论是进行过滤、排序还是进行数据转换都非常方便。
使用字典实现单词统计
Dictionary 非常适合做数据统计的场景,例如:统计文本中每个单词出现的次数。
using System;
using System.Collections.Generic;
namespace AppDictionary
{
internal class Program
{
static void Main(string[] args)
{
string text = "the quick brown fox jumps over the lazy dog";
Dictionary<string, int> wordCount = new Dictionary<string, int>();
// 分割文本并统计每个单词出现的次数
foreach (string word in text.Split(' '))
{
if (wordCount.ContainsKey(word))
{
wordCount[word]++;
}
else
{
wordCount[word] = 1;
}
}
// 输出统计结果
foreach (var item in wordCount)
{
Console.WriteLine($"单词 '{item.Key}' 出现了 {item.Value} 次");
}
}
}
}复制

利用 Dictionary 实现简单缓存
在一些场景下,为了防止重复计算,可以使用 Dictionary 作为简单的缓存容器。下面演示用 GetOrAdd
方法完成缓存逻辑的思路:
using System;
using System.Collections.Generic;
namespace AppDictionary
{
internal class Program
{
static void Main(string[] args)
{
var cache = new SimpleCache<string, int>();
// 第一次访问时,值不存在,需要调用工厂方法计算
int value = cache.GetOrAdd("key1", k => 100);
Console.WriteLine(value);
// 第二次访问同一个键,直接从缓存返回,无需重新计算
int sameValue = cache.GetOrAdd("key1", k => 200);
Console.WriteLine(sameValue);
}
}
publicclass SimpleCache<TKey, TValue>
{
private Dictionary<TKey, TValue> _cache = new Dictionary<TKey, TValue>();
public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
{
if (!_cache.TryGetValue(key, out TValue value))
{
value = valueFactory(key);
_cache[key] = value;
}
return value;
}
public void Remove(TKey key)
{
_cache.Remove(key);
}
}
}复制

上例展示了通过 TryGetValue
来检查缓存中是否已存在对应 Key 的值,如果不存在则使用 委托 去生成并存储,再返回给调用方。
实用场景与最佳实践
使用
TryGetValue
代替索引器尽量使用
TryGetValue(key, out value)
来获取值,避免出现KeyNotFoundException
异常。考虑并发安全
在多线程环境下使用
Dictionary
时,请考虑线程安全问题。可以使用lock
机制或使用线程安全版本的ConcurrentDictionary<TKey, TValue>
。及时释放或移除无用数据
Dictionary 无法自动清理,若要防止内存浪费,应及时调用
Remove
或重新初始化字典。合理设置容量
如果已经知道字典大致存储多少条(如数百万级),可以在初始化时为 Dictionary 提供容量参数,减少后续扩容带来的性能开销。
应用在高频检索场景
例如:
- 频繁访问某些表配置信息。
- 实现对象或数据缓存。
- 快速根据 ID 查找对象。
- 实现简单的路由或者映射关系。
注意内存占用
对于超大规模数据(如上百万级别),需要权衡内存开销与检索效率之间的平衡,合理使用数据结构及数据库或其它缓存。
总结
在 C# 开发中,Dictionary<TKey, TValue>
提供了快速查找、灵活存储和高效管理的特性,是构建许多功能性模块(如缓存系统、统计表、设置管理等)的核心工具。
通过本文你可以了解到:
- Dictionary 的基本特性和使用方法
- 结合 LINQ 在字典中灵活查询、转换及排序
- 用字典进行数据统计和简单缓存的业务实践
- 实际开发中的使用注意事项与最佳实践
无论是在处理少量数据还是大量数据时,只要场景需要快速查找或键值映射,Dictionary
都能有效提升程序的可维护性和性能。结合本文提供的诸多示例,你可以在实际项目中更加得心应手地使用 C# 的字典结构来解决问题。祝你编程愉快!
如果你正在从事上位机、自动化、机器视觉、物联网(IOT)项目或数字化转型方面的工作,欢迎加入我的微信圈子!在这里,我们不仅可以轻松畅聊最新技术动态和行业趋势,还能够在技术问题上互相帮助和支持。我会尽量利用我的知识和经验来帮助你解决问题,当然也期待从大家的专业见解中学习和成长。无论你是新手还是老鸟,期待与志同道合的朋友交流心得,一起进步!