C#, Как обработать несколько исключений, который делает все равно?

По моему скромному мнению...

Ограничение операции "C_UD" к хранимым процедурам могут сохранить логику целостности данных в одном месте. Это может также быть сделано путем ограничения операций "C_UD" единственным средним слоем изделия.

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

6
задан Konamiman 15 June 2015 в 09:32
поделиться

6 ответов

Вы все делаете правильно (вы должны перехватывать только те исключения, которые собираетесь обрабатывать, и нет способа перехватить более одного типа исключений в одном блоке catch ), но в качестве альтернативы вы можете просто catch (Exception ex) , проверить тип исключения, и, если это не тот, который вы ожидаете, просто бросьте его снова, что-то вроде этого :

var exceptionTypes=new Type[] {
    typeof(FileNotFoundException),
    typeof(ArgumentNullException),
    //...add other types here
};

catch(Exception ex) {
    if(exceptionTypes.Contains(ex.GetType()) {
        HandleException(ex);
    } else {
        throw;
    }
}

ОБНОВЛЕНИЕ: С C # 6 (идущим вместе с Visual Studio 2015) вместо этого вы можете сделать следующее:

catch(Exception ex) when (exceptionTypes.Contains(ex.GetType()) {
    HandleException(ex);
}
12
ответ дан 8 December 2019 в 13:00
поделиться

Я бы провел рефакторинг следующим образом: -

public class Sample
{
    public void LoadControl( ControlDestination controlDestination, string filename, object parameter )
    {
        HandleExceptions( HandleException, () =>
        {
            //.... your code
        } );
    }

    private void HandleExceptions( Action<Exception> handler, Action code )
    {
        try
        {
            code();
        }
        catch ( FileNotFoundException e )
        {
            handler( e );
        }
        catch ( ArgumentNullException e )
        {
            handler( e );
        }
        catch ( HttpException e )
        {
            handler( e );
        }
        catch ( IncorrectInheritanceException e )
        {
            handler( e );
        }
    }

    private void HandleException( Exception exception )
    {
        // ....
    }
}

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

private void HandleExceptions( Action<Exception> handler, Action code )
    {
        try
        {
            code();
        }
        catch ( Exception e )
        {
            if ( e is FileNotFoundException
                || e is ArgumentNullException
                || e is HttpException
                || e is IncorrectInheritanceException )
                handler( e );
            else
                throw;
        }
    }
3
ответ дан 8 December 2019 в 13:00
поделиться

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

Код работает, определяя исключения как аргументы универсального типа для функции дескриптора. Затем эти конкретные типы перехватываются, но передаются универсальному обработчику в качестве базового класса. Я не добавлял HandleAndThrow, но его можно добавить по желанию. Также измените название по своему вкусу.

    public static void Handle<T>(Action action, Action<T> handler)
        where T : Exception
    {
        try
        {
            action();
        }
        catch (T exception)
        {
            handler(exception);
        }
    }

    public static void Handle<T1, T2>(Action action, Action<Exception> handler)
        where T1 : Exception
        where T2 : Exception
    {
        try
        {
            action();
        }
        catch (T1 exception)
        {
            handler(exception);
        }
        catch (T2 exception)
        {
            handler(exception);
        }
    }

    public static void Handle<T1, T2, T3>(Action action, Action<Exception> handler)
        where T1 : Exception
        where T2 : Exception
        where T3 : Exception
    {
        try
        {
            action();
        }
        catch (T1 exception)
        {
            handler(exception);
        }
        catch (T2 exception)
        {
            handler(exception);
        }
        catch (T3 exception)
        {
            handler(exception);
        }
    }

    public static void Handle<T1, T2, T3, T4>(Action action, Action<Exception> handler)
        where T1 : Exception
        where T2 : Exception
        where T3 : Exception
        where T4 : Exception
    {
        try
        {
            action();
        }
        catch (T1 exception)
        {
            handler(exception);
        }
        catch (T2 exception)
        {
            handler(exception);
        }
        catch (T3 exception)
        {
            handler(exception);
        }
        catch (T4 exception)
        {
            handler(exception);
        }
    }
}

public class Example
{
    public void LoadControl()
    {
        Exceptions.Handle<FileNotFoundException, ArgumentNullException, NullReferenceException>(() => LoadControlCore(10), GenericExceptionHandler);   
    }

    private void LoadControlCore(int myArguments)
    {
        //execute method as normal
    }

    public void GenericExceptionHandler(Exception e)
    {
        //do something
        Debug.WriteLine(e.Message);
    }        
}
3
ответ дан 8 December 2019 в 13:00
поделиться

LIBTINYC Мэтта Пейтрека имеет модуль argcargv.cpp, который принимает строку и преобразует ее в массив аргументов с учетом аргументов в кавычках. Обратите внимание, что он специфичен для Windows, но довольно прост, поэтому его будет легко перейти на любую платформу, которую вы хотите.

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

0
ответ дан 8 December 2019 в 13:00
поделиться

Я собираюсь ответить, что это не зависит от языка:

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

2. Поймайте самую общую форму исключения, которая есть. Просто

catch(Exception e)
{
    ...
}

3. Возможно, вы хотите перехватить только некоторые исключения, не перехватывая все исключения , что вы бы сделали, если бы вы только что выполнили №2.

Сделайте то, что вы делали в # 2, плюс измените HandleException, чтобы обрабатывать только определенные типы исключений. Таким образом, вам нужно будет набрать команду только один раз, и она по-прежнему более компактна, чем указано выше.

private void HandleException(Exception e) throws Excpetion
{
    // Reject some types of exceptions
    if (!((e is FileNotFoundException) ||
        (e is ArgumentNullException) ||
        (e is HttpException ) ||
        (e is IncorrectInheritanceException )))
    {
        throw;
    }

    //Rest of code
    ...
}

Изменить:

Я вижу, что Konamiman имеет улучшенную версию этого третьего варианта. Я говорю: давай.

0
ответ дан 8 December 2019 в 13:00
поделиться

Я бы сделал это так

public void LoadControl(ControlDestination controlDestination, string filename, object parameter)
{
    try
    {
        // Get filename with extension
        string file = GetControlFileName(filename);

        // Check file exists
        if (!File.Exists(file))
            throw new FileNotFoundException();

        // Load control from file
        Control control = LoadControl(filename);

        // Check control extends BaseForm
        if (control is BaseForm)
        {
            // Set current application on user control
            ((BaseForm)control).CurrentApplication = this;
            ((BaseForm)control).Parameter = parameter;

            // Set web user control id
            control.ID = filename;

            Panel currentPanel = null;

            switch (controlDestination)
            {
                case ControlDestination.Base:
                    // Set current panel to Base Content
                    currentPanel = pnlBaseContent;
                    // Set control in viewstate
                    this.BaseControl = filename;
                    break;
                case ControlDestination.Menu:
                    // Set current panel to Menu Content
                    currentPanel = pnlMenuContent;
                    // Set control in ViewState
                    this.MenuBaseControl = filename;
                    break;
            }

            currentPanel.Controls.Clear();
            currentPanel.Controls.Add(control);
            UpdateMenuBasePanel();
            UpdateBasePanel();

        }
        else
        {
            throw new IncorrectInheritanceException();
        }
    }
    catch (Exception e)
    {
        HandleException(e);
    }
}


public void HandleException(Exception e)
{
    if (e is FileNotFoundException
            || e is ArgumentNullException
            || e is HttpException
            || e is IncorrectInheritanceException)
    {
        // Load error control which shows big red cross
        LoadControl(ControlDestination.Menu, "~/Controls/Error.ascx", null);

        // Store error in database
        DHS.Core.DhsLogDatabase.WriteError(exception.ToString());

        // Show error in errorbox on master
        Master.ShowAjaxError(this, new CommandEventArgs("ajaxError", exception.ToString()));
    }
}
0
ответ дан 8 December 2019 в 13:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: