Выход из класса из C # с использованием Catch - PullRequest
1 голос
/ 19 марта 2012

Я ищу лучший метод обработки ошибок в классе ac # winforms, который у меня есть.Суть приложения в том, что оно имеет анализатор данных, который анализирует данные на предмет статистики и других подобных вещей.Однако я ищу правильный способ обработки ABORT.

Например, у меня есть класс с именем Analyzer

namespace PHOEBE
{
    public class Analyzer
    {
        public Analyzer(){
            DoAnalysis();
            DoFurtherAnalysis();
        }

    public class DoAnalysis(){
        try{
            Convert.ToInt32("someNumber...."); //obviously fails..
        }
        catch{
          //ERROR OCCURRED, ABORT ALL ANALYSIS
            return;
        }
    }
}

Очевидно, что при вызове DoAnalysis () произойдетбыть ошибкой, которая возникаетБлок catch поймает исключение.Однако, когда происходит этот перехват, он вернется в конструктор и запустит DoFutureAnalysis ().Это проблема.

Я знаю, что вы можете возвращать значения из каждого метода, где каждое значение указывает на определенный результат (т. Е. 1 = успех, 0 = сбой).Однако многие методы, которые я вызываю, уже используют возвращаемые значения.Я также мог бы использовать логическое значение, которое помечается при возникновении ошибки, и проверять это значение перед вызовом следующего метода из конструктора, но проверка этого значения каждый раз раздражает и повторяет.

Я действительно надеялся на что-то вроде "механизма прерывания", который я мог бы использовать.Есть ли другие способы обойти это?Какие-нибудь интересные обходные пути для этого?

Предположим, этот класс вызывается из формы.

Ответы [ 8 ]

11 голосов
/ 19 марта 2012

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

Обычно я нахожу исключения для перехвата довольно редкими - обычно это либо на верхнем уровне (чтобы остановить отключение всего сервера только из-за одного запроса), либо для преобразования исключения одного вида в другое, чтобы поддерживать соответствующие абстракции.

6 голосов
/ 19 марта 2012

Я действительно надеялся на что-то вроде "механизма прерывания", который я мог бы использовать.Есть ли другие способы обойти это?Какие-нибудь интересные обходные пути для этого?

Да, есть.Это называется обработка исключений .

Давайте перепишем ваш код:

namespace PHOEBE
{
    public class Analyzer
    {
        public Analyzer()
        {
            try
            {
                DoAnalysis();
                DoFurtherAnalysis();
            }
            catch
            {
                //ERROR OCCURRED, ABORT ALL ANALYSIS
                return;
            }
        }

    public class DoAnalysis()
    {
        Convert.ToInt32("someNumber...."); //obviously fails..
    }
}

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

На несвязанной ноте: пожалуйста, постарайтесь отловить как можно более конкретные исключения, в данном случае FormatException

3 голосов
/ 19 марта 2012

Вы подрываете существующий механизм "прерывания", отлавливая исключение, с которым вы ничего не делаете, и проглатывая его.

В этом случае вам не следует использовать блок try{}catch{}, и пусть возникнет исключительная ситуация, и приложение прекратит работу.

1 голос
/ 19 марта 2012

Не вижу ничего раздражающего в возврате и проверке bool возвращаемого значения из функции. Это гораздо лучшее решение, чем сложное управление внутренним состоянием, которое вы наверняка перепутаете через пару месяцев, когда вернетесь к своему коду.

Сделать код простым и строгим. Это не раздражает, это хорошо.

В вашем конкретном случае, если вы хотите просто прервать все , только не catch исключение, это прервет вашу программу.

1 голос
/ 19 марта 2012

Самый простой обходной путь - , не поймите исключение . Если бы это произошло, оно бы прошло сразу за функцией DoFurtherAnalysis() и вышло бы на исходный вызов.

0 голосов
/ 19 марта 2012

Вы можете просто переместить DoFurtherAnalysis(); в блок try

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

0 голосов
/ 19 марта 2012

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

Во-вторых, (и вы будете читать во многих темах здесь), как вы справляетесь с ошибками, действительно зависит от приложения и ожиданий ваших пользователей. Некоторые ошибки могут быть исправлены изменениями входных данных. Другие могут случиться посреди ночи, если анализ занимает много времени, и вы можете продолжить другой анализ, регистрируя эту ошибку.

Так что я думаю, что мы действительно собираемся ответить вам за дополнительную информацию об этом.

0 голосов
/ 19 марта 2012

использовать try ... catch в конструкторе?

...