Bu sözlük anahtarının C # 'da olup olmadığını nasıl tespit edebilirim?


498

Kişi verileri ile Exchange Web Hizmetleri Yönetilen API ile çalışıyorum. İşlevsel , ancak ideal değil aşağıdaki kodu var :

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

Dediğim gibi, bu kod çalışır . Şimdi mümkünse biraz daha az emmek istiyorum .

Erişmeye çalışmadan önce sözlükte anahtarın varlığını kontrol etmeme izin veren herhangi bir yöntem bulamıyorum ve (ile .ToString()) okumaya çalışırsam ve mevcut değilse bir istisna atılır:

500
Verilen anahtar sözlükte yoktu.

Daha az emmek için bu kodu nasıl yeniden düzenleyebilirim (hala işlevsel olsa da)?

Yanıtlar:


889

Şunları kullanabilirsiniz ContainsKey:

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

veya TryGetValue:

dict.TryGetValue(key, out value);

Güncelleme : bir açıklamaya göre, burada gerçek sınıf bir IDictionarydeğil bir PhysicalAddressDictionary, bu yüzden yöntemler Containsve TryGetValueaynı şekilde çalışırlar.

Örnek kullanım:

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

Güncelleme 2: İşte çalışma kodu (soru asker tarafından derlenmiştir)

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

... iç koşul gerekli her anahtar için gerektiği şekilde tekrarlanır. TryGetValue, her FizikselAddressKey (Ev, İş vb.) Başına yalnızca bir kez yapılır.


TryGetValueBen bu sayfayı buldum çünkü, en iyi bahis olabilir gibi bir yaklaşım görünüyor: goo.gl/7YN6 ... ama emin nasıl kullanılacağını değilim. Yukarıdaki rowkodumda bir 'DataRow` nesnesidir, bu yüzden örnek kodunuzun doğru olduğundan emin değilim ...
Adam Tuttle

Burada ne yanlış yapıyorum? c.PhysicalAddresses.TryGetValue(c.PhysicalAddresses[PhysicalAddressKey.Home].Street, row["HomeStreet"]);
Adam Tuttle

1
@Adam Tuttle: İkinci parametre bir çıkış parametresidir. İşe yarayan kodu tahmin etmeye çalışacağım ve cevabımı güncelleyeceğim ama burada derleyemediğim için hataları affetmeniz gerekecek.
Mark Byers

İyi cevap. SO'daki tutarlılık için, "soru asker" terimi yerine "OP" (Orijinal Poster kısaltması) kullanılabilir.
Lave Loos

Bir astar (gerektirir C# 7.0)row["HomeStreet"] = c.PhysicalAddresses.TryGetValue(PhysicalAddressKey.Home, out PhysicalAddressEntry entry) ? entry.Street.ToString() : null;
Ivan García Topete

12

Ne tür c.PhysicalAddresses? Eğer öyleyse Dictionary<TKey,TValue>, ContainsKeyyöntemi kullanabilirsiniz .


Teşekkürler, Adam, bu gerçekten yararlı değil. Sınıf hiyerarşisi nedir? Baz tipi nedir?
John Saunders


3

Ben bir Sözlük kullanın ve tekrarlama ve olası eksik anahtarlar nedeniyle, hızlı bir şekilde küçük bir yöntem yamalı:

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

Aramak:

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

İşi alır.


1

İşte bugün pişirdiğim küçük bir şey. Benim için iş gibi görünüyor. Temel olarak, bir denetim yapmak için temel ad alanınızdaki Ekle yöntemini geçersiz kılar ve ardından gerçekten eklemek için tabanın Ekle yöntemini çağırırsınız. Umarım bu senin için çalışır

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());
        }
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.