क्या किसी शब्दकोश में आइटम जोड़ने का एक और अधिक सुरुचिपूर्ण तरीका है <> सुरक्षित रूप से?


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
उत्कृष्ट, साधारण एहसास नहीं था कि ऐड / ओवरराइट मुद्दे का ख्याल रखा गया, अच्छा।
एडवर्ड तुंगाय जुले

49

क्या गलत है...

dict[key] = view;

यदि यह गैर-मौजूद है तो यह स्वचालित रूप से कुंजी जोड़ देगा।


3
मुझे लगता है कि एक बात ध्यान देने योग्य है कि यदि आप एक इंट स्टोर कर रहे हैं, dict[key] += amountतो काम नहीं करेगा यदि कुंजी मौजूद नहीं है
क्रिस एस

22

केवल

dict[key] = view;

Dictionary.Item के MSDN प्रलेखन से

निर्दिष्ट कुंजी के साथ जुड़ा हुआ मूल्य। यदि निर्दिष्ट कुंजी नहीं मिली है, तो एक गेट ऑपरेशन एक KeyNotFoundException को फेंकता है, और एक सेट ऑपरेशन निर्दिष्ट कुंजी के साथ एक नया तत्व बनाता है

मेरा जोर


10

हमेशा की तरह जॉन स्कीट सही उत्तर के साथ प्रकाश की गति के साथ वहाँ पहुँच जाता है, लेकिन दिलचस्प बात यह है कि आप अपने SafeAdd को IDfox पर एक्सटेंशन विधि के रूप में भी लिख सकते थे।

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 और इसके बाद के संस्करण के लिए लागू है।
मेहरदाद अफश्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.