Один обработчик исключений для всех исключений класса - PullRequest
20 голосов
/ 03 августа 2009

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

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

UPDATE:


Многие из вас спрашивают меня, почему. Причина в том, что я вызываю источник данных различными методами. поэтому в моем классе есть функции getData1, gedData2, getData3, getData4, ...., getDataN. Проблема в том, что нет способа проверить, открыто ли соединение, и создание нового соединения очень и очень дорого. Поэтому я пытаюсь повторно использовать соединение, и если соединение при следующем вызове не удалось, я бы поймал это, переподключился и попытался снова. Вот почему мне нужен этот блок try / catch all.

чтобы сделать это для всех функций:

try{    
   datasource.getData()
}
catch(ConnectionException)
{
   datasource.Connect();
   datasource.getData()
}

Спасибо

Ответы [ 6 ]

22 голосов
/ 31 января 2011

Вы могли бы использовать делегата для передачи кода вашего метода в одну попытку try, как в следующем примере:

    private void GlobalTryCatch(Action action)
    {
        try
        {
            action.Invoke();
        }
        catch (ExpectedException1 e)
        {
            throw MyCustomException("Something bad happened", e);
        }
        catch (ExpectedException2 e)
        {
            throw MyCustomException("Something really bad happened", e);
        }
    }

    public void DoSomething()
    {
        GlobalTryCatch(() =>
        {
            // Method code goes here
        });
    }
13 голосов
/ 03 августа 2009

Я не могу понять причину, по которой вы можете извлечь выгоду из обработки всех исключений в классе с помощью одного метода (можете ли вы уточнить? Мне интересно ...)

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

Есть хорошая библиотека постобработки сборки под названием PostSharp , которую вы можете настроить с помощью атрибутов методов вашего класса:

Вы можете определить такой аспект (с сайта PostSharp):

public class ExceptionDialogAttribute : OnExceptionAspect
{
    public override void OnException(MethodExecutionEventArgs eventArgs)
    {
        string message = eventArgs.Exception.Message;
        MessageBox.Show(message, "Exception");
        eventArgs.FlowBehavior = FlowBehavior.Continue;
    }
}

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

public class YourClass {

    // ...

    [ExceptionDialog]
    public string DoSomething(int param) {
        // ...
    }
}

Вы также можете применить атрибут ко всему классу, например:

[ExceptionDialog]
public class YourClass {
    // ...
    public string DoSomething(int param) {
        // ...
    }
    public string DoSomethingElse(int param) {
        // ...
    }
}

Это будет применять рекомендации (код обработки исключений) ко всем методам в классе.

1 голос
/ 03 августа 2009

Исключения на самом деле не связаны с классом, а ориентированы на метод / callstack. В общем случае объект не должен пытаться обрабатывать исключения из своих собственных методов. Это зависит от тех, кто вызывает эти методы.

1 голос
/ 03 августа 2009

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

1 голос
/ 03 августа 2009

Я не думаю, что есть. Вы можете перенести команду try / catch на вызывающую сторону, но это не очень хороший дизайн. Может быть лучше разделить его на другой класс и использовать Reflection для вызова методов, например:

public class MyClass {}
public class MySafeClass {
    public void CallMethod(string name, object[] param) {
        Type t = typeof(MyClass);
        MyClass mc = new MyClass();
        try {
            t.GetMethod(name).Invoke(mc, param);
        }
        catch {
            //...;
        }
    }

}

Но вы не должны! Это не очень хорошая практика.

Другой метод все еще использует try/catch, но имеет один метод для выдачи исключений и т. Д. Обратно пользователю:

public class MyClass {
    void DoException(string message) {
        throw new Exception(message);
    }
}

Но это все же не слишком хороший вариант.

Я не понимаю, почему это было бы ужасно - даже если вы просто заключите весь метод в один try / catch с сообщением. Это может быть осуществимо.

Также лучше оставить их и передать обратно вызывающему, возможно, в try/finally.

Попробовать / поймать все не сложно, особенно с помощью фрагментов в Visual Studio и SharpDevelop.

0 голосов
/ 03 августа 2009

Возможно, вы захотите использовать метод main / try / catch для вашего основного метода, хотя я считаю, что это серьезное неправильное использование обработки исключений, за исключением того, что вы хотите добавить регистратор или sth.

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