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
public bool TryGetValue (
PhysicalAddressKey key,
out PhysicalAddressEntry physicalAddress
)