views:

316

answers:

3

I am working with the Exchange Web Services Managed API, with contact data. I have the following code, which is functional, but not 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...
}

As I said, this code works. Now I want to make it suck a little less, if possible.

I can't find any methods that allow me to check for the existence of the key in the dictionary before attempting to access it, and if I try to read it (with .ToString()) and it doesn't exist then an exception is thrown:

500
The given key was not present in the dictionary.

How can I refactor this code to suck less (while still being functional)?

A: 

PhysicalAddressDictionary.TryGetValue

 public bool TryGetValue (
    PhysicalAddressKey key,
    out PhysicalAddressEntry physicalAddress
     )
David Neale
+1  A: 

What is the type of c.PhysicalAddresses? If it's Dictionary<TKey,TValue>, then you can use the ContainsKey method.

John Saunders
Exchange webservices "PhysicalAddressDictionary" type...
Adam Tuttle
Thanks, Adam, that's really (not) helpful. What's the class hierarchy? What's the base type?
John Saunders
+6  A: 

You can use ContainsKey:

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

or TryGetValue:

dict.TryGetValue(key, out value);

Update: according to a comment the actual class here is not an IDictionary but a PhysicalAddressDictionary, so the methods are Contains and TryGetValue but they work in the same way.

Example usage:

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

Update 2: here is the working code (compiled by question asker)

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

...with the inner conditional repeated as necessary for each key required. The TryGetValue is only done once per PhysicalAddressKey (Home, Work, etc).

Mark Byers
+1 for `TryGetValue`
SLaks
The `TryGetValue` approach seems like it may be the best bet, since I found this page: http://goo.gl/7YN6... but I'm not sure how to use it. In my code above, `row` is a 'DataRow` object, so I'm not sure your example code is right, though...
Adam Tuttle
What am I doing wrong, here? `c.PhysicalAddresses.TryGetValue(c.PhysicalAddresses[PhysicalAddressKey.Home].Street, row["HomeStreet"]);`
Adam Tuttle
@Adam Tuttle: The second parameter is an out parameter. I'll try to guess at code that works and update my answer but you'll have to forgive mistakes as I can't compile it here.
Mark Byers
Thanks for your help. <3 SO. Amazingly fast and accurate, once again! :D
Adam Tuttle
@Adam Tuttle: Thanks for correcting my code. I refactored it incorrectly.
Mark Byers