2

创建自定义异常类的原因是——至少对我而言——我需要传输额外的信息,例如一些域对象。
为了实现这一点,我向我的异常类添加了一个只读属性,并提供了一个初始化这个属性并只允许非空值的构造函数。

现在,根据MSDN代码分析,每个 Exception 类型都应该至少有四个特定的构造函数。

最终结果是可以创建没有我的自定义属性集的自定义异常类的实例。

这有两个问题:

  1. 每个异常处理程序都必须检查该属性是否null
  2. 如果没有该附加属性,某些异常处理程序将无法做任何有用的事情。

如何解决这个困境?

4

1 回答 1

1

你能为你的域对象提供一个默认值吗,也许是一个空对象?( http://en.wikipedia.org/wiki/Null_Object_pattern ) 这样,您的任何异常处理程序都不需要更聪明。当使用域对象的任何方法或属性时,让域对象的 Null Object 实例不执行任何操作。

另一种选择是使用 [SuppressMessage] 来避免代码分析消息,然后没有零参数的构造函数。那么问题就变成了你的类不再是可序列化的。这对您来说可能是也可能不是问题。

最后,考虑创建一个中间类,将其命名为 DomainObjectExceptionHandler。它负责在发生异常时处理:

 public abstract class DomainObjectExceptionHandlerBase {
     public abstract void HandleException();
 }

然后有一个实现知道当一个真正的域对象发生异常时该怎么做:

 public class DomainObjectExceptionHandler : DomainObjectExceptionHandlerBase {
     private DomainObject domainObject;
     public DomainObjectExceptionHandler(DomainObject domainObject) {
         this.domainObject = domainObject;
     public override void HandleException() { 
         // do real recovery work with the domain object
     }
 }

然后是一个什么都不做的空对象:

public class NullDomainObjectExceptionHandler : DomainObjectExceptionHandlerBase {
    public override void HandleException() { 
        // do nothing
    }
}

现在您的异常类可以具有四个推荐的签名,包括:

public class DomainObjectException {
    public DomainObjectException() {
        this.Handler = new NullDomainObjectExceptionHandler();
    }

    public DomainObjectException(DomainObject domainObject) {
        this.Handler = new DomainObjectExceptionHandler(domainObject);
    }

    public DomainObjectExceptionHandlerBase Handler { get; private set; }
}

您的抛出代码如下所示:

if (domainObject.IsUnhappy())
    throw new DomainObjectException(domainObject);

您的异常处理程序如下所示:

try {
    FrobulateDomainObjects();
} catch (DomainObjectException ex) {
    ex.Handler.HandleException();
}

注意异常处理程序不需要知道 DomainObject 的存在,它将它委托给 DomainObjectExceptionHandler。

于 2013-02-26T08:03:02.623 回答