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

답변:


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
훌륭합니다. 간단한 할당이 추가 / 덮어 쓰기 문제를 처리한다는 사실을 몰랐습니다.
Edward Tanguay

49

무슨 일이야 ...

dict[key] = view;

존재하지 않는 경우 자동으로 키를 추가합니다.


3
내가 생각하는 것 중 하나는 int를 저장 dict[key] += amount하면 키가 존재하지 않으면 작동하지 않는다는 것입니다.
Chris S

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.