辞書<>にアイテムを安全に追加するよりエレガントな方法はありますか?


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

回答:


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これは2番目のCustomersエントリでスローされるため機能しません。


6
すばらしい、単純な割り当てが追加/上書きの問題を処理することを理解していませんでした。
Edward Tanguay

49

どうしたの...

dict[key] = view;

キーが存在しない場合は、自動的に追加されます。


3
私が思うことの一つは、あなたが、int型を格納している場合ことは注目に値するdict[key] += amountしませんワーク鍵が存在しない場合
クリス・S

22

単に

dict[key] = view;

Dictionary.ItemのMSDNドキュメントから

指定されたキーに関連付けられた値。指定されたキーが見つからない場合、get操作はKeyNotFoundExceptionをスローし、set操作は指定されたkeyで新しい要素を作成します

私の強調


10

いつものように、John Skeetは正しい答えで照明速度を取得しますが、興味深いことに、SafeAddをIDictionaryの拡張メソッドとして記述することもできます。

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

9

インデクサーを使用することは明らかに特定の問題に対する正しい答えですが、既存の型に機能を追加する問題に対するもう1つのより一般的な答えは、拡張メソッドを定義することです。

明らかにこれは特に有用な例ではありませんが、次に実際に必要になるときに心に留めておくべきことは次のとおりです。

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、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.