Попробуй поймать блок. Какое решение лучше - PullRequest
1 голос
/ 31 августа 2010

Мне показалось разумным использовать:

int.TryParse()

и просто, если вместо:

int.Parse()

внутри блока try. Пока я не нашел этот образец в MS шаблон и практика

    /// <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;
    }

Не лучше ли использовать метод Contains insted? С другой стороны, я прочитал, что CLR может оптимизировать try-catch для простого перехода.

Ответы [ 4 ]

4 голосов
/ 31 августа 2010

Да, не используйте блоки catch для этого. Я не уверен, где вы нашли этот код, но подозреваю, что он невероятно стар. Метод Contains () намного быстрее. Кроме того, проверьте метод TryGetValue () класса словаря.

2 голосов
/ 31 августа 2010

Я не уверен, каким должен быть тип изолированныйStore, но если это словарь, то isolatedStore.TryGetValue(key, out value) будет моим предпочтительным способом проверки.

А для присваивания, isolatedStore[key] = value никогда не должно выдавать исключение, если ключ не равен нулю, что, по-видимому, справедливо, чтобы пузырек до вызывающей стороны. По сути, использование индексатора само по себе является операцией добавления или обновления, хотя он не сообщит вам, было ли ранее значение.

Так что да, точно так же, как int.Parse против int.TryParse, предпочтите методы, которые дают вам ответы, с которыми вы можете иметь дело (например, TryGetValue), а не методы, которые выдают исключения (по крайней мере, в восстанавливаемых ситуациях, подобных этим).

Бен Фойгт говорит о безопасности потоков. Использование TryGetValue и присвоение значения с помощью indexer (isolatedStore[key]) вместо .Add() устранит любые исключения, но операция все еще не будет атомарной.

1 голос
/ 31 августа 2010

TryGetValue лучше, чем Contains, потому что он избегает условия гонки.Но если у вас есть несколько потоков, обращающихся к Словарю, вам придется так или иначе обрабатывать исключения, хотя вы можете уменьшить количество раз, когда вы платите штраф за исключение.

1 голос
/ 31 августа 2010

Я запустил тесты, и TryParse работал намного быстрее, чем Parse, потому что .NET, казалось, тратит много времени на генерацию исключения, которое выдается, если Parse не удался, но в TryParse он мог просто выбросить «false». 1001 *

Я не уверен, что любой из них "лучше", но мои тесты показали, что TryParse, кажется, работает быстрее, и я думаю, что TryParse делает код более читабельным, чем множество блоков try / catch.

Edit: ваш пример кода, похоже, не имеет ничего общего с анализом int.

...