634 Stimmen

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

Ich arbeite mit der Exchange Web Services Managed API, mit Kontaktdaten. Ich habe den folgenden Code, der lautet funktionell , 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 Werke . Jetzt möchte ich es zum Kotzen finden ein bisschen weniger wenn möglich.

Ich kann keine Methoden finden, die es mir erlauben, das Vorhandensein des Schlüssels im Wörterbuch zu überprüfen, bevor ich versuche, darauf zuzugreifen, und wenn ich versuche, ihn zu lesen (mit .ToString() ) und es existiert nicht, wird eine Ausnahme ausgelöst:

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

Wie kann ich diesen Code so umgestalten, dass er weniger nervt (und trotzdem noch funktioniert)?

1100voto

Mark Byers Punkte 761508

Sie können verwenden ContainsKey :

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

ou TryGetValue :

dict.TryGetValue(key, out value);

Update : Einem Kommentar zufolge ist die eigentliche Klasse hier nicht eine IDictionary sondern eine PhysicalAddressDictionary Die Methoden sind also Contains y TryGetValue aber sie funktionieren auf dieselbe Weise.

Beispiel für die Verwendung:

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

Update 2: Hier ist der funktionierende Code (kompiliert 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 bei Bedarf für jeden erforderlichen Schlüssel wiederholt wird. TryGetValue wird nur einmal pro PhysicalAddressKey (Home, Work, etc.) ausgeführt.

17voto

John Saunders Punkte 159011

Was ist die Art der c.PhysicalAddresses ? Wenn es Dictionary<TKey,TValue> dann können Sie die ContainsKey Methode.

7voto

JohanE Punkte 133

Ich verwende ein Wörterbuch, und wegen der vielen Wiederholungen und der möglicherweise fehlenden Schlüssel habe ich mir schnell eine kleine Methode ausgedacht:

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

Ich rufe sie an:

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

Erledigt die Aufgabe.

6voto

David Neale Punkte 15770

PhysicalAddressDictionary.TryGetValue

 public bool TryGetValue (
    PhysicalAddressKey key,
    out PhysicalAddressEntry physicalAddress
     )

3voto

xul8tr Punkte 21

Hier ist eine Kleinigkeit, die ich mir heute ausgedacht habe. Scheint bei mir zu funktionieren. 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 bei Ihnen

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X