Исключения для потока управления - PullRequest
3 голосов
/ 06 октября 2008

Здесь есть интересный пост об этом, касающийся потока управления между приложениями.

Ну, недавно я столкнулся с интересной проблемой. Генерация n-го значения в потенциально (практически) бесконечной рекурсивной последовательности. Этот конкретный алгоритм будет по крайней мере в 10-15 стековых ссылок глубоко в точке, где он будет успешным. Моей первой мыслью было создать исключение SuccessException, которое выглядело примерно так (C #):

class SuccessException : Exception
{
    public string Value
    { get; set; }

    public SuccessException(string value)
        : base()
    {
        Value = value;
    }
}

Тогда сделайте что-то вроде этого:

try
{
    Walk_r(tree);
}
catch (SuccessException ex)
{
    result = ex.Value;
}

Затем мои мысли блуждали обратно сюда, где я слышал снова и снова, чтобы никогда не использовать исключения для управления потоком. Есть ли оправдание? И как бы вы структурировали что-то подобное, если бы вы это реализовали?

Ответы [ 7 ]

5 голосов
/ 06 октября 2008

В этом случае я бы посмотрел на ваш метод Walk_r, у вас должно быть что-то, что возвращает значение, выдавая исключение, указывающее на успех, это НЕ распространенная практика, и, как минимум, будет ОЧЕНЬ запутанным для любого, кто видит код. Не говоря уже о накладных расходах, связанных с исключениями.

1 голос
/ 06 октября 2008

walk_r должен просто возвращать значение при попадании. Это довольно стандартный пример рекурсии. Единственная потенциальная проблема, которую я вижу, заключается в том, что вы сказали, что она потенциально бесконечна, что должно быть компенсировано в коде walk_r путем сохранения счетчика глубины рекурсии и остановки на некотором максимальном значении.

Исключение на самом деле делает кодирование очень странным, поскольку вызов метода теперь генерирует исключение для возврата значения, вместо простого возврата "обычно".

try
{
    Walk_r(tree);
}
catch (SuccessException ex)
{
    result = ex.Value;
}

становится

result = Walk_r(tree);
0 голосов
/ 06 октября 2008

Я собираюсь сыграть здесь адвоката дьявола и сказать, что придерживайтесь исключения, чтобы указать на успех. Бросать / ловить может быть дорого, но это может быть незначительным по сравнению со стоимостью самого поиска и, возможно, менее запутанным, чем ранний выход из метода.

0 голосов
/ 06 октября 2008

Использование исключений в обычном программном потоке в моей книге - одна из худших практик за всю историю. Подумайте о бедном соке, который ищет проглоченные исключения и запускает отладчик, настроенный на остановку при возникновении исключения. Этот чувак сейчас злится ... и у него есть топор. : P

0 голосов
/ 06 октября 2008

Проблема с использованием исключений заключается в том, что они (по большому счету) очень неэффективны и медленны. Конечно, было бы так просто иметь условие if внутри рекурсивной функции, чтобы просто возвращать, когда и когда это необходимо. Честно говоря, с количеством памяти на современном ПК маловероятно (хотя и не невозможно) переполнение стека с помощью небольшого количества рекурсивных вызовов (<100). </p>

Если стек является реальной проблемой, то может возникнуть необходимость проявить «творческий подход» и реализовать «стратегию поиска с ограниченной глубиной», разрешить функции вернуться из рекурсии и возобновить поиск с последнего (самого глубокого) узла .

Подводя итог: Исключения следует использовать только в исключительных обстоятельствах, успех вызова функции, который, я не считаю, квалифицируется как таковой.

0 голосов
/ 06 октября 2008

Почему бы просто не вернуть полученное значение? Если он вообще что-то возвращает, предположим, что он успешен. Если он не может вернуть значение, это означает, что цикл завершился неудачно.

Если вам нужно вернуться из-за сбоя, я бы порекомендовал вам сгенерировать исключение.

0 голосов
/ 06 октября 2008

Не очень хорошая идея создавать исключения как часть алгоритма, особенно в .net. В некоторых языках / платформах исключения являются довольно эффективными, когда они выбрасываются, и обычно это происходит, когда, например, исчерпывается итерация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...