views:

185

answers:

4

It seemed a reasonable pattern for me to use:

int.TryParse()

and simple if, rather than:

int.Parse()

inside the try block. Till I found this sample in MS pattern & practices

    /// <summary>
    /// Update a setting value for our application. If the setting does not
    /// exist, then add the setting.
    /// </summary>
    /// <param name="Key"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    public bool AddOrUpdateValue(string Key, Object value)
    {
        bool valueChanged = false;
        try
        {
            // if new value is different, set the new value.
            if (isolatedStore[Key] != value)
            {
                isolatedStore[Key] = value;
                valueChanged = true;
            }
        }
        catch (KeyNotFoundException)
        {
            isolatedStore.Add(Key, value);
            valueChanged = true;
        }
        catch (ArgumentException)
        {
            isolatedStore.Add(Key, value);
            valueChanged = true;
        }
        catch (Exception e)
        {
            Debug.WriteLine("Exception while using IsolatedStorageSettings: " + e.ToString());
        }

        return valueChanged;
    }

Isn't it better to use Contains method insted? On the other hand, I have read that CLR can optimize try-catch to simple goto.

+1  A: 

I've run tests and TryParse ran much quicker than Parse because .NET seemed to spend a lot of time generating the exception to throw if Parse failed, but in TryParse it was able to just throw out a "false."

I'm not sure that either one is "better", but my tests said that TryParse seemed to be faster, and I think TryParse makes for more readable code than lots of try/catch blocks.

Edit: your code sample doesn't seem to have anything to do with int parsing.

Yoenhofen
+4  A: 

Yes, do not use catch blocks for this. I'm not sure where you found that code but I suspect it's incredibly old. The Contains() method is much faster. Additionally, check out the TryGetValue() method of the dictionary class.

Steve Michelotti
It is not. it's super new :)http://msdn.microsoft.com/en-us/library/ff637516%28v=VS.92%29.aspxSetting Sample
lukas
+1  A: 

TryGetValue is better than Contains because it avoids a race condition. But if you have multiple threads accessing the Dictionary you'll have to handle exceptions one way or another, although you can minimize the number of times you pay the exception penalty.

Ben Voigt
Dictionaries are not inherrently thread-safe, so I don't see how the race condition applies. If two threads try to write to your dictionary and you are not locking, you are already in deep trouble. (and of course if the writes need to be locked, so do the reads) My understanding is that TryGetValue is better because it requires only a *single* hash lookup into the dictionary, instead of one for Contains and the other to fetch the value.
Kirk Woll
Just a difference in granularity on the locking. And different types of "better". Better correctness because it's more atomic, better performance because it's only one hash lookup.
Ben Voigt
+2  A: 

I'm not sure what type isolatedStore is supposed to be, but if it is a Dictionary, then isolatedStore.TryGetValue(key, out value) would be my preferred way of checking.

And for assignment, isolatedStore[key] = value should never throw an exception unless key is null, which seems fair to let bubble up to the caller. Essentially, using the indexer is a add-or-update operation by itself, although it won't tell you if the value was previously there.

So yes, just like int.Parse vs int.TryParse, prefer the methods that give you responses you can deal with (like TryGetValue) rather than methods that throw exceptions (at least in recoverable situations like these).

Ben Voigt brings up a great point about thread safety. Using TryGetValue and assigning the value with the indexer (isolatedStore[key]) instead of .Add() will eliminate any exceptions, but the operation still won't be atomic.

Brad
@Brad: If I could vote you up twice I would.
Chris Lively
@Chris: Thanks!@Raj: Thanks for the formatting changes, usually I'm better about that.
Brad