-
C#教程之Dictionary扩展基础类向字典中添加键和值
向字典中添加键和值
添加键和值使用 Add 方法,但很多时候,我们是不敢轻易添加的,因为 Dictionary<TKey, TValue> 不允许重复,尝试添加重复的键时 Add 方法引发 ArgumentException。
大多时候,我们都会写成以下的样子:
复制代码 代码如下:
var dict = new Dictionary<int, string>();
// ...
// 情形一:不存在才添加
if (dict.ContainsKey(2) == false) dict.Add(2, "Banana");
// 情形二:不存在添加,存在则替换
if (dict.ContainsKey(3) == false) dict.Add(3, "Orange");
else dict[3] = "Orange";
其实,第二种情形可以写如下书写
复制代码 代码如下:
dict[3] = "Orange";
不过好多朋友都会对这种方式表示疑虑,不太确定这样会不会出问题。
不管是上面的哪种写法,用字典时最大的感觉就是担心,怕出异常,因此代码会写的很罗嗦。
我每次用字典时都这样,时间长了,实在是厌烦了,索性扩展一下,用以下两个方法来应对上面两种情形:
复制代码 代码如下:
/// <summary>
/// 尝试将键和值添加到字典中:如果不存在,才添加;存在,不添加也不抛导常
/// </summary>
public static Dictionary<TKey, TValue> TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
{
if (dict.ContainsKey(key) == false) dict.Add(key, value);
return dict;
}
/// <summary>
/// 将键和值添加或替换到字典中:如果不存在,则添加;存在,则替换
/// </summary>
public static Dictionary<TKey, TValue> AddOrReplace<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value)
{
dict[key] = value;
return dict;
}
TryAdd 和 AddOrReplace 这两个方法具有较强自我描述能力,用起来很省心,而且也简单:
复制代码 代码如下:
dict.TryAdd(2, "Banana");
dict.AddOrReplace(3, "Orange");
或者像 Linq 或 jQuery 一样连起来写:
复制代码 代码如下:
dict.TryAdd(1, "A")
.TryAdd(2, "B")
.AddOrReplace(3, "C")
.AddOrReplace(4, "D")
.TryAdd(5, "E");
再来看另外一个问题:
获取值
从字典中获取值通常使用如下方式:
复制代码 代码如下:
string v = "defaultValue";
// 方式一
if (dict.ContainsKey(3)) v = dict[3];
// 方式二
bool isSuccess = dict.TryGetValue(3, out v);
使用索引的方式获取前一定先判断,否则不存在时会引发 KeyNotFoundException 异常。
我尤其讨厌第二种方式,因为采用 out 要提前声明一个变量,代码至少要两行,不够简洁。
看下 GetValue 扩展:
复制代码 代码如下:
/// <summary>
/// 获取与指定的键相关联的值,如果没有则返回输入的默认值
/// </summary>
public static TValue GetValue<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue defaultValue = default(TValue))
{
return dict.ContainsKey(key) ? dict[key] : defaultValue;
}
使用方便:
复制代码 代码如下:
var v1 = dict.GetValue(2); //不存在则返回 null
var v2 = dict.GetValue(2, "abc"); //不存在返回 ”abc“
一行代码能搞定。
批量添加
List<T> 类有个 AddRange 方法,可以不用 foreach 循环直接向当前集合加入另外一个集合:
复制代码 代码如下:
List<string> roles = new List<string>();
roles.AddRange(new[] { "role2", "role2" });
roles.AddRange(user.GetRoles());
相当方便,可怜 Dictionary<TKey, TValue> 类没有,幸好有扩展方法:
复制代码 代码如下:
/// <summary>
/// 向字典中批量添加键值对
/// </summary>
/// <param name="replaceExisted">如果已存在,是否替换</param>
public static Dictionary<TKey, TValue> AddRange<TKey, TValue>(this Dictionary<TKey, TValue> dict, IEnumerable<KeyValuePair<TKey, TValue>> values, bool replaceExisted)
{
foreach (var item in values)
{
if (dict.ContainsKey(item.Key) == false || replaceExisted)
dict[item.Key] = item.Value;
}
return dict;
}
使用示例:
复制代码 代码如下:
var dict1 = new Dictionary<int, int>()
.AddOrReplace(2, 2)
.AddOrReplace(3, 3);
var dict2 = new Dictionary<int, int>()
.AddOrReplace(1, 1)
.AddOrReplace(2, 1)
.AddRange(dict1, false);
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式