有没有更优雅的方式将项目安全地添加到 Dictionary<> 中?

Posted

技术标签:

【中文标题】有没有更优雅的方式将项目安全地添加到 Dictionary<> 中?【英文标题】:Is there a more elegant way of adding an item to a Dictionary<> safely? 【发布时间】:2010-11-13 17:35:45 【问题描述】:

我需要将键/对象对添加到字典中,但我当然需要先检查键是否已存在,否则我会收到“字典中已存在键”错误。下面的代码解决了这个问题,但很笨重。

在不创建这样的字符串辅助方法的情况下,有什么更优雅的方法?

using System;
using System.Collections.Generic;

namespace TestDictStringObject

    class Program
    
        static void Main(string[] args)
        
            Dictionary<string, object> currentViews = new Dictionary<string, object>();

            StringHelpers.SafeDictionaryAdd(currentViews, "Customers", "view1");
            StringHelpers.SafeDictionaryAdd(currentViews, "Customers", "view2");
            StringHelpers.SafeDictionaryAdd(currentViews, "Employees", "view1");
            StringHelpers.SafeDictionaryAdd(currentViews, "Reports", "view1");

            foreach (KeyValuePair<string, object> pair in currentViews)
            
                Console.WriteLine("0 1", pair.Key, pair.Value);
            
            Console.ReadLine();
        
    

    public static class StringHelpers
    
        public static void SafeDictionaryAdd(Dictionary<string, object> dict, string key, object view)
        
            if (!dict.ContainsKey(key))
            
                dict.Add(key, view);
            
            else
            
                dict[key] = view;
            
        
    

【问题讨论】:

【参考方案1】:

只需使用索引器 - 如果它已经存在,它将覆盖,但它没有 首先存在:

Dictionary<string, object> currentViews = new Dictionary<string, object>();
currentViews["Customers"] = "view1";
currentViews["Customers"] = "view2";
currentViews["Employees"] = "view1";
currentViews["Reports"] = "view1";

如果键的存在表明存在错误(因此您希望它抛出),则基本上使用Add,否则使用索引器。 (这有点像强制转换和使用as 进行引用转换的区别。)

如果您使用的是 C# 3 并且您有一组不同的键,您可以让这更加整洁:

var currentViews = new Dictionary<string, object>()

     "Customers", "view2" ,
     "Employees", "view1" ,
     "Reports", "view1" ,
;

这在你的情况下不起作用,因为集合初始化器总是使用Add,这将抛出第二个Customers条目。

【讨论】:

太好了,没有意识到简单的分配可以解决添加/覆盖问题,很好。【参考方案2】:

怎么了……

dict[key] = view;

如果不存在,它会自动添加密钥。

【讨论】:

我认为值得注意的一点是,如果您存储的是 int,如果密钥不存在,dict[key] += amount 将不起作用【参考方案3】:

简单

dict[key] = view;

来自 Dictionary.Item 的 MSDN 文档

与 指定的键。如果指定的键是 未找到,get 操作会抛出 KeyNotFoundException 和一个 set 操作创建一个新元素 指定的键

我的重点

【讨论】:

【参考方案4】:

像往常一样,John Skeet 以闪电般的速度获得正确答案,但有趣的是,您也可以将 SafeAdd 编写为 IDictionary 上的扩展方法。

public static void SafeAdd(this IDictionary<K, T>. dict, K key, T value)...

【讨论】:

【参考方案5】:

虽然使用索引器显然是解决您的特定问题的正确答案,但为现有类型添加附加功能的问题的另一个更一般的答案是定义扩展方法。

显然,这不是一个特别有用的示例,但在您下次发现真正需要时需要牢记:

public static class DictionaryExtensions

    public static void SafeAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, 
                                             TKey key, TValue value)
    
        dict[key] = value;
    

【讨论】:

我要提一下这只适用于 C# 3.0 及更高版本。

以上是关于有没有更优雅的方式将项目安全地添加到 Dictionary<> 中?的主要内容,如果未能解决你的问题,请参考以下文章

有没有更优雅的方法来添加可为空的整数?

程序员应该如何设计更优雅的Token认证方式?

如何更优雅地在表格视图中添加/删除单元格?

更简洁优雅的 VARIANT 类型使用方式

有没有比这段代码更优雅的方式将 XML 文档转换为 Java 中的字符串?

IntelliJ IDEA - 如何优雅地添加 .gitignore 到 Project?