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)?
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.
Was ist die Art von c.PhysicalAddresses
? Wenn es sich um Dictionary<TKey,TValue>
handelt, können Sie die Methode ContainsKey
verwenden.
PhysicalAddressDictionary.TryGetValue
public bool TryGetValue (
PhysicalAddressKey key,
out PhysicalAddressEntry physicalAddress
)
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.
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());
}
}
}