是否有更安全的方式将项目安全地添加到Dictionary <>中?


141

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

什么是更优雅的方法而不做这样的字符串助手方法呢?

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;
            }
        }
    }
}

Answers:


246

只需使用索引-如果它已经存在,它将覆盖,但它不具备在那里第一次:

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条目上抛出。


6
太好了,没有意识到简单的分配可以解决添加/覆盖问题,很好。
爱德华·坦格


22

只是

dict[key] = view;

来自Dictionary.Item的MSDN文档

与指定键关联的值。如果找不到指定的键,则get操作将引发KeyNotFoundException,而set操作将使用指定的key创建一个新元素

我的重点


10

像往常一样,约翰·斯基特(John Skeet)以正确的答案进入照明​​速度,但是有趣的是,您也可以在IDictionary上编写SafeAdd作为扩展方法。

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

9

尽管显然可以使用索引器来解决您的特定问题,但是对于向现有类型添加附加功能的问题,另一个更通用的答案是定义扩展方法。

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

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

2
我提到这仅适用于C#3.0及更高版本。
Mehrdad Afshari,2009年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.