Dictionary扩展基础类向字典中添加键和值

 更新时间:2013年11月20日 14:40:35   作者:  
Dictionary<TKey, TValue> 类是常用的一个基础类,但用起来有时确不是很方便。本文逐一讨论,并使用扩展方法解决

向字典中添加键和值
添加键和值使用 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);

相关文章

  • C#实现应用程序的监控与调试的示例代码

    C#实现应用程序的监控与调试的示例代码

    日志记录是软件开发中不可或缺的功能,它能帮助开发者在应用程序运行时记录重要信息,本文就来介绍一下常用日志记录功能以及常用的日志库,感兴趣的可以了解一下
    2024-03-03
  • C# 添加、修改以及删除Excel迷你图表的实现方法

    C# 添加、修改以及删除Excel迷你图表的实现方法

    下面小编就为大家分享一篇C# 添加、修改以及删除Excel迷你图表的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • C#窗体读取EXCEL并存入SQL数据库的方法

    C#窗体读取EXCEL并存入SQL数据库的方法

    这篇文章主要介绍了C#窗体读取EXCEL并存入SQL数据库的方法,实例简述了实现读取excel及写入SQL数据库的原理与技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • c# 编写的简单飞行棋游戏

    c# 编写的简单飞行棋游戏

    这个简单的飞行棋游戏主要是讲的方法怎么应用,充分的去理解方法和方法的调用。整体收获还是很大的。感兴趣的朋友可以参考下
    2021-06-06
  • C#使用IronPython调用python代码的实现示例

    C#使用IronPython调用python代码的实现示例

    本文主要介绍了在C#中使用IronPython调用Python代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-01-01
  • C#实现给DataGrid单元行添加双击事件的方法

    C#实现给DataGrid单元行添加双击事件的方法

    这篇文章主要介绍了C#实现给DataGrid单元行添加双击事件的方法,较为详细的分析了C#给DataGrid单元添加双击事件的步骤及相关实现代码,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • c# 反射用法及效率对比

    c# 反射用法及效率对比

    这篇文章主要介绍了c# 反射用法及效率对比,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下
    2021-02-02
  • C#操作串口通信协议Modbus的常用方法介绍

    C#操作串口通信协议Modbus的常用方法介绍

    这篇文章介绍了C#操作串口通信协议Modbus的常用方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C# Socket文件上传至服务器的操作方法

    C# Socket文件上传至服务器的操作方法

    文件上传有FTP、WebApi、WebService等等,这次我们来实现一个基于socket通信的本地客户端上传文件到服务器的例子,这篇文章主要介绍了C# Socket文件上传至服务器的操作方法,需要的朋友可以参考下
    2024-05-05
  • C#中将DataTable转换成CSV文件的方法

    C#中将DataTable转换成CSV文件的方法

    DataTable用于在.net项目中,用于缓存数据,DataTable表示内存中数据的一个表,在.net项目中运用C#将DataTable转化为CSV文件,接下来通过本文给大家提供一个通用的方法,感兴趣的朋友可以参考下
    2016-10-10

最新评论