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

Edw*_*uay 130 c# collections dictionary

我需要将键/对对添加到字典中,但我当然需要首先检查密钥是否已经存在,否则我得到" 密钥已存在于字典中 "错误.下面的代码解决了这个问题,但很笨重.

在没有像这样的字符串帮助方法的情况下,这样做更优雅的方法是什么?

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 232

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

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

基本上使用,Add如果密钥的存在指示一个错误(所以你想要它抛出)和否则索引器.(这有点像转换和使用as参考转换之间的区别.)

如果您使用的是C#3 并且拥有一组独特的按键,则可以使其更加整洁:

var currentViews = new Dictionary<string, object>()
{
    { "Customers", "view2" },
    { "Employees", "view1" },
    { "Reports", "view1" },
};
Run Code Online (Sandbox Code Playgroud)

但是,这在你的情况下是行不通的,因为集合初始化器总是使用Add它将抛出第二个Customers条目.

  • 优秀,没有实现简单的任务照顾添加/覆盖问题,很好. (6认同)

Meh*_*ari 46

怎么了......

dict[key] = view;
Run Code Online (Sandbox Code Playgroud)

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

  • 我认为值得注意的一件事是,如果你存储一个 int,如果键不存在,`dict[key] += amount` 将不起作用 (13认同)

Ste*_*ham 21

只是

dict[key] = view;
Run Code Online (Sandbox Code Playgroud)

从Dictionary.Item的MSDN文档

与指定键关联的值.如果未找到指定的键,则get操作将引发KeyNotFoundException,并且set操作将使用指定的键创建新元素.

我的重点


roh*_*agg 10

像往常一样John Skeet带着合适的答案进入灯光速度,但有趣的是你也可以在IDictionary上编写SafeAdd作为扩展方法.

public static void SafeAdd(this IDictionary<K, T>. dict, K key, T value)...
Run Code Online (Sandbox Code Playgroud)


Dan*_*ker 7

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

显然,这不是一个特别有用的例子,但下次你发现真正需要时要记住:

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

  • 我会提到这仅适用于 C# 3.0 及更高版本。 (2认同)