向代理抛出异常的惯用方法

时间:2012-05-26 07:08:25

标签: c# .net .net-3.5

我有一个监控设备的监控类,并报告该设备是否成功接收到可用数据。这可以随时发生。

客户端通过传递委托创建自己的监视器,启动它并等待成功读取数据或某种特定于域的异常类型(一种基本异常类型)

抛出基本异常类型的子类型并使客户端能够单独响应每个子类型的惯用方法是什么?

public class MyMonitor
{
  private SuccessHandler _successHandler;
  private ErrorHandler _errorHandler;
  public delegate void SuccessHandler(MyDTO result);
  public delegate void ErrorHandler(MyBaseException exception);

  public MyMonitor(SuccessHandler successHandler, ErrorHandler errorHandler) {
    _successHandler = successHandler;
    _errorHandler = errorHandler;
  }

  public void start() {
    try {
      _successHandler(new MyDTP().doSomethingRisky());
    } catch(Exception e) {
      _errorHandler(e);
    }
  }
}

public class Client {
  static void Main(string[] args) {
    MyMonitor monitor = new MyMonitor(new MyMonitor.SuccessHandler(handleSuccess), new MyMonitor.ErrorHandler(handleException));
    monitor.start();
  }

  static void handleSuccess(MyDTO result) {
    // do something with result
  }

  static void handleException(MyBaseException e) {
    try {
      throw e;
    } catch(UserException mbe) {
      // present message to user
    } catch(DataNotFoundException se) {
      // log error and show generic error message
    } catch(UnexpectedException ue) {
      // log error and try to hide it from the user
    }
  }
}

1 个答案:

答案 0 :(得分:2)

那么,为什么不处理main中的异常而不是monitor-class?

如果这不是一个选项,你有(至少)两种选择:

static void handleException(MyBaseException e)
{
  if (e is UserException)
  {
    // present message to user
  }
  else if (e is DataNotFoundException)
  {
    // log error and show generic error message
  }
  elseif (e is UnexpectedException)
  {
    // log error and try to hide it from the user
  }
  else
  {
    // might want to rethrow the exception, do a general handling,...
  }
}

这样你就不必重新抛出异常,只是为了再次捕获它。 但是如果要处理多个子类型,这可能会变得很难看,这就是multidispatch的用武之地。

static void HandleException(MyBaseException e)
{
  HandleSubException((dynamic)e);
}

static void HandleSubException(MyBaseException e)
{
    // might want to rethrow the exception, do a general handling,...
}

static void HandleSubException(DataNotFoundExceptione)
{
    // log error and show generic error message
}

static void HandleSubException(UnexpectedException e)
{
    // log error and try to hide it from the user
}

static void HandleSubException(UserExceptione)
{
    // present message to user
}

现在,您可以在自己的方法中使用每个异常,并且更容易阅读和维护。 话虽如此,我并不完全确定这是否属于最佳做法。