sp2 software services office microsoft kit exchange ews development c# exchangewebservices ews-managed-api

software - ¿Cómo puedo detectar si esta clave de diccionario existe en C#?



exchange web services office 365 (5)

Estoy trabajando con la API administrada de servicios web de Exchange, con datos de contacto. Tengo el siguiente código, que es funcional , pero no 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... }

Como dije, este código funciona . Ahora quiero hacerlo chupar un poco menos , si es posible.

No puedo encontrar ningún método que me permita verificar la existencia de la clave en el diccionario antes de intentar acceder a ella, y si intento leerla (con .ToString() ) y no existe, entonces existe una excepción. es aventado:

500
La clave dada no estaba presente en el diccionario.

¿Cómo puedo refactorizar este código para que chupe menos (mientras sigo siendo funcional)?


¿Cuál es el tipo de c.PhysicalAddresses ? Si es Dictionary<TKey,TValue> , entonces puede usar el método ContainsKey .


Aquí hay algo que cociné hoy. Parece funcionar para mi. Básicamente, reemplaza el método Agregar en su espacio de nombres base para hacer una comprobación y luego llama al método Agregar de la base para agregarlo. Espero que esto funcione para usted

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


Puedes usar ContainsKey :

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

o TryGetValue :

dict.TryGetValue(key, out value);

Actualización : según un comentario, la clase real aquí no es un IDictionary sino un PhysicalAddressDictionary , por lo que los métodos son Contains y TryGetValue pero funcionan de la misma manera.

Ejemplo de uso:

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

Actualización 2: aquí está el código de trabajo (compilado por el que pregunta)

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

... con el condicional interno repetido según sea necesario para cada clave requerida. TryGetValue solo se realiza una vez por PhysicalAddressKey (Inicio, Trabajo, etc.).


Utilizo un Diccionario y debido a la repetición y las posibles claves faltantes, rápidamente uní un pequeño método:

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

Llamándolo:

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

Hace el trabajo hecho


TryGetValue

public bool TryGetValue ( PhysicalAddressKey key, out PhysicalAddressEntry physicalAddress )