views:

236

answers:

4
public static Dictionary<string,List<LookupItem>> dict;

if (dict == null)
{
   dict = IsolatedStorage.GetDropDowns();
   return dict["Priority"]
}
else
   return dict["Priority"];

or

try
{
   return dict["Priority"];
}
catch(KeyNotFoundException e)
{
   dict = IsolatedStorage.GetDropDowns();
   return dict["Priority"];
}

This is a silverlight application, i have dropdowns cached in isolated storage (if i had to query the wcf service for every lookup then the datagrid takes forever to appear, im well aware that dropdowns could become outdated and i have a means of updating the dictionary when new values are added/removed via a callback), in my xaml, i have a converter that converts the Id returned from a dbquery to the related LookupItem object. I know im never supposed to use try's and catch's as part of application logic, but i realy need the fastest possible approach therefore im willing to ignore that architectural no-no. The reason the dictionary would become null is since im storing the dictionary as a static var in an arbitary class, if the user had to hit F5 to refresh the page, the dictionary would lose its values since the xap file is reloaded and my caching page that executes on login would not execute."Priority" contains a of List. LookupItem contains Key/Value that is needed for ComboBoxes and so on.

1) Is a dictionary the most effecient way of storing this information? 2) which of the two approaches will yield the fastest possible return of the List?

+8  A: 

Well you're lacking braces to start with, but I'd write it as:

if (dict == null)
{
   dict = IsolatedStorage.GetDropDowns();
}
return dict["Priority"];

Note that you'll probably need some locking to make this thread-safe. In fact, why not just write it as:

public static Dictionary<string,List<LookupItem>> dict 
    = IsolatedStorage.GetDropDowns();

to start with? Then you know it'll never be null.

Anyway, please don't use the second idea. The check for nullity is insanely fast, and anyway you'll still fail with a NullReferenceException rather than a KeyNotFoundException...

If you really want to behave differently depending on whether or not a key is present, you should use (assuming dict is already non-null):

List<LookupItem> list;
if (!dict.TryGetValue("Priority", out list))
{
    // Deal with the key being missing
}
else
{
    return list;
}

I would also question your judgement about needing this to be "the fastest possible approach" - once you've made sure that you only perform the fetch from WCF once, are you sure it's really a performance bottleneck? I'd be shocked if that were the case.

Jon Skeet
Check my answer, it was going to this comment, but then I thought it was important enough to merit an answer.
NickLarsen
@NickLarsen: But the OP has already said he doesn't care about the cleanliness of it - which is a mistake IMO (see my final paragraph).
Jon Skeet
This could potentially be called 10 000 times in a single datagrid, since it exists to bind an Id to a dropdown key/value pair for multiple columns of a grid
Neil
+1  A: 
  1. A dictionary seems like a reasonable approach to storing the data.
  2. Your two code samples are testing different things. For ensuring dict is non-null, see Jon's answer.

The best alternative to try/catch(KeyNotFoundException) is TryGetValue:

List<LookupItem> priority = null;
if(!dict.TryGetValue("Priority", out priority))
    throw new ApplicationException("Could not find Priority list.");

return priority;
dahlbyk
A: 

From your code, dict == null does not appear to be an exceptional case, so you should use the first method anyway. Try catch should not be used as a logical step because that is not what it is designed for.

NickLarsen
I clearly stated in the question that i know try/catch should not be used as a logical step, i wanted to know IL wise which is faster, irrespective of cleanliness
Neil
i cant declare the dict with the GetDropDowns();since the caching of dropdowns only takes place once the user logs-in and is then kept in localstorage
Neil
+1  A: 

Apart from the fact that your first example is lacking some braces, it'll be much faster, because an if-expression is executed in virtually no time, whereas throwing an exception, creating the necessary handlers and traversing the stack frame is somewhat more work for the CLR...

So if you're calling the 'dict' field less than say 500.000 times, it's clearly #1. Regarding your first question: I'm not totally sure, because I'm not a WPF-hero, but usually there's rarely something more efficient than a Dictionary for this kind of data.

And btw.: You wouldn't get a 'KeyNotFoundException' in the above case, but a 'NullReferenceException'...

Thomas Weller
Thanks, i actually wrote the example from memory and made a mistake, it was supposed to be NullReference, i was thinking about 2 different problems at the same time, which in my case, both were solved in a single thread.
Neil