webentwicklung-frage-antwort-db.com.de

Wie kann ich feststellen, ob dieser Wörterbuchschlüssel in C # vorhanden ist?

Ich arbeite mit der verwalteten Exchange Web Services-API mit Kontaktdaten. Ich habe den folgenden Code, der funktional ist, aber nicht ideal:

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

Wie gesagt, dieser Code funktioniert. Jetzt möchte ich es lutschen lassen etwas weniger, wenn möglich.

Ich kann keine Methoden finden, mit denen ich die Existenz des Schlüssels im Wörterbuch überprüfen kann, bevor ich versuche, darauf zuzugreifen. Wenn ich versuche, ihn zu lesen (mit .ToString()), ist er nicht vorhanden Ausnahme wird ausgelöst:

500
Der angegebene Schlüssel war im Wörterbuch nicht vorhanden.

Wie kann ich diesen Code umgestalten, um weniger zu saugen (während er noch funktioniert)?

431
Adam Tuttle

Sie können ContainsKey verwenden:

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

oder TryGetValue :

dict.TryGetValue(key, out value);

Update : Nach einem Kommentar ist die eigentliche Klasse hier keine IDictionary, sondern eine PhysicalAddressDictionary , also sind die Methoden Contains und TryGetValue , aber sie funktionieren auf die gleiche Weise.

Anwendungsbeispiel:

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

Update 2: Hier ist der Arbeitscode (zusammengestellt vom Fragesteller)

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

... wobei die innere Bedingung für jeden erforderlichen Schlüssel nach Bedarf wiederholt wird. Der TryGetValue wird nur einmal pro PhysicalAddressKey (Home, Work, etc) durchgeführt.

795
Mark Byers

Was ist die Art von c.PhysicalAddresses? Wenn es sich um Dictionary<TKey,TValue> handelt, können Sie die Methode ContainsKey verwenden.

11
John Saunders

PhysicalAddressDictionary.TryGetValue

 public bool TryGetValue (
    PhysicalAddressKey key,
    out PhysicalAddressEntry physicalAddress
     )
5
David Neale

Ich verwende ein Wörterbuch und habe wegen der Wiederholbarkeit und der Möglichkeit fehlender Schlüssel schnell eine kleine Methode zusammengefügt:

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

Nennen Sie es:

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

Erledigt die Arbeit.

3
JohanE

Hier ist etwas, das ich mir heute ausgedacht habe. Scheint für mich zu arbeiten. Grundsätzlich überschreiben Sie die Add-Methode in Ihrem Basis-Namespace, um eine Prüfung durchzuführen, und rufen dann die Add-Methode der Basis auf, um sie tatsächlich hinzuzufügen. Ich hoffe, das funktioniert für Sie

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());
        }
    }
}
1
xul8tr