मैं यह कैसे पता लगा सकता हूं कि यह शब्दकोश कुंजी C # में मौजूद है?


498

मैं संपर्क डेटा के साथ एक्सचेंज वेब सेवा प्रबंधित एपीआई के साथ काम कर रहा हूं। मेरे पास निम्नलिखित कोड है, जो कार्यात्मक है , लेकिन आदर्श नहीं है:

foreach (Contact c in contactList)
{
    string openItemUrl = "https://" + service.Url.Host + "/owa/" + c.WebClientReadFormQueryString;

    row = table.NewRow();
    row["FileAs"] = c.FileAs;
    row["GivenName"] = c.GivenName;
    row["Surname"] = c.Surname;
    row["CompanyName"] = c.CompanyName;
    row["Link"] = openItemUrl;

    //home address
    try { row["HomeStreet"] = c.PhysicalAddresses[PhysicalAddressKey.Home].Street.ToString(); }
    catch (Exception e) { }
    try { row["HomeCity"] = c.PhysicalAddresses[PhysicalAddressKey.Home].City.ToString(); }
    catch (Exception e) { }
    try { row["HomeState"] = c.PhysicalAddresses[PhysicalAddressKey.Home].State.ToString(); }
    catch (Exception e) { }
    try { row["HomeZip"] = c.PhysicalAddresses[PhysicalAddressKey.Home].PostalCode.ToString(); }
    catch (Exception e) { }
    try { row["HomeCountry"] = c.PhysicalAddresses[PhysicalAddressKey.Home].CountryOrRegion.ToString(); }
    catch (Exception e) { }

    //and so on for all kinds of other contact-related fields...
}

जैसा कि मैंने कहा, यह कोड काम करता है । अब मैं इसे कम से कम चूसना चाहता हूं , यदि संभव हो तो।

मुझे कोई भी ऐसा तरीका नहीं मिल सकता है जो मुझे इसे एक्सेस करने के प्रयास से पहले शब्दकोश में कुंजी के अस्तित्व की जांच करने की अनुमति दे, और अगर मैं इसे (साथ .ToString()) पढ़ने की कोशिश करता हूं और यह मौजूद नहीं है, तो एक अपवाद फेंक दिया जाता है:

500
दी गई कुंजी शब्दकोश में मौजूद नहीं थी।

मैं इस कोड को कम चूसने के लिए कैसे रिफ्लेक्टर कर सकता हूं (जबकि अभी भी कार्यात्मक है)?

जवाबों:


889

आप उपयोग कर सकते हैं ContainsKey:

if (dict.ContainsKey(key)) { ... }

या TryGetValue:

dict.TryGetValue(key, out value);

अपडेट : एक टिप्पणी के अनुसार यहां वास्तविक वर्ग एक नहीं IDictionaryबल्कि एक है PhysicalAddressDictionary, इसलिए विधियां हैं Containsऔर TryGetValueवे उसी तरह से काम करते हैं।

उदाहरण उपयोग:

PhysicalAddressEntry entry;
PhysicalAddressKey key = c.PhysicalAddresses[PhysicalAddressKey.Home].Street;
if (c.PhysicalAddresses.TryGetValue(key, out entry))
{
    row["HomeStreet"] = entry;
}

अद्यतन 2: यहाँ काम कोड (प्रश्न पूछने वाले द्वारा संकलित) है

PhysicalAddressEntry entry;
PhysicalAddressKey key = PhysicalAddressKey.Home;
if (c.PhysicalAddresses.TryGetValue(key, out entry))
{
    if (entry.Street != null)
    {
        row["HomeStreet"] = entry.Street.ToString();
    }
}

... आंतरिक कुंजी के साथ आवश्यक प्रत्येक कुंजी के लिए आवश्यक दोहराया। TryGetValue केवल एक बार PhysicalAddressKey (गृह, कार्य, आदि) के अनुसार किया जाता है।


TryGetValueदृष्टिकोण है कि यह सबसे अच्छा शर्त हो सकता है, के बाद से मैं इस पेज पाया लगता है: goo.gl/7YN6 ... लेकिन मुझे यकीन है कि यह कैसे उपयोग करने के लिए नहीं कर रहा हूँ। ऊपर मेरे कोड में, rowएक 'DataRow` ऑब्जेक्ट है, इसलिए मुझे यकीन नहीं है कि आपका उदाहरण कोड सही है, हालांकि ...
एडम टटलू

मुझसे यहां क्या गलत हो रहा है? c.PhysicalAddresses.TryGetValue(c.PhysicalAddresses[PhysicalAddressKey.Home].Street, row["HomeStreet"]);
एडम टटल

1
@ एडम टटल: दूसरा पैरामीटर एक आउट पैरामीटर है। मैं उस कोड पर अनुमान लगाने की कोशिश करूँगा जो मेरे जवाब को काम करता है और अद्यतन करता है लेकिन आपको गलतियों को माफ़ करना होगा क्योंकि मैं इसे यहाँ संकलित नहीं कर सकता।
मार्क बायर्स

अच्छा उत्तर। SO पर स्थिरता के लिए, "प्रश्न पूछने वाला" शब्द को "ओपी" (मूल पोस्टर के लिए छोटा) द्वारा प्रतिस्थापित किया जा सकता है।
लोवोस

एक लाइनर (की आवश्यकता है C# 7.0)row["HomeStreet"] = c.PhysicalAddresses.TryGetValue(PhysicalAddressKey.Home, out PhysicalAddressEntry entry) ? entry.Street.ToString() : null;
इवान गार्सिया टोपेटे

12

किस प्रकार का है c.PhysicalAddresses? यदि यह है Dictionary<TKey,TValue>, तो आप ContainsKeyविधि का उपयोग कर सकते हैं ।


धन्यवाद, एडम, यह वास्तव में (सहायक नहीं) है। वर्ग पदानुक्रम क्या है? आधार प्रकार क्या है?
जॉन सॉन्डर्स


3

मैं एक डिक्शनरी का उपयोग करता हूं और दोहराव और संभव लापता चाबियों के कारण, मैंने जल्दी से एक छोटी विधि को एक साथ पैच किया:

 private static string GetKey(IReadOnlyDictionary<string, string> dictValues, string keyValue)
 {
     return dictValues.ContainsKey(keyValue) ? dictValues[keyValue] : "";
 }

इसे कॉल करना:

var entry = GetKey(dictList,"KeyValue1");

काम हो जाता है।


1

यहाँ कुछ है जो मैंने आज पकाया है। लगता है मेरे लिए काम करता है। मूल रूप से आप चेक करने के लिए अपने बेस नेमस्पेस में ऐड मेथड को ओवरराइड करते हैं और फिर वास्तव में जोड़ने के लिए बेस के ऐड मेथड को कॉल करते हैं। उम्मीद है इससे आपका काम बनेगा

using System;
using System.Collections.Generic;
using System.Collections;

namespace Main
{
    internal partial class Dictionary<TKey, TValue> : System.Collections.Generic.Dictionary<TKey, TValue>
    {
        internal new virtual void Add(TKey key, TValue value)
        {   
            if (!base.ContainsKey(key))
            {
                base.Add(key, value);
            }
        }
    }

    internal partial class List<T> : System.Collections.Generic.List<T>
    {
        internal new virtual void Add(T item)
        {
            if (!base.Contains(item))
            {
                base.Add(item);
            }
        }
    }

    public class Program
    {
        public static void Main()
        {
            Dictionary<int, string> dic = new Dictionary<int, string>();
            dic.Add(1,"b");
            dic.Add(1,"a");
            dic.Add(2,"c");
            dic.Add(1, "b");
            dic.Add(1, "a");
            dic.Add(2, "c");

            string val = "";
            dic.TryGetValue(1, out val);

            Console.WriteLine(val);
            Console.WriteLine(dic.Count.ToString());


            List<string> lst = new List<string>();
            lst.Add("b");
            lst.Add("a");
            lst.Add("c");
            lst.Add("b");
            lst.Add("a");
            lst.Add("c");

            Console.WriteLine(lst[2]);
            Console.WriteLine(lst.Count.ToString());
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.