我应该在自己的非LINQ代码中使用DuplicateKeyException吗?

Pau*_*ner 3 .net inversion-of-control

我正在为一些关键业务运营编写审计服务.该服务正在使用IoC模式实现:

public interface IAuditWriter
{
    void WriteAction(int key, string value);
}
Run Code Online (Sandbox Code Playgroud)

因此,我需要它来提出不是特定于实现的异常.

审计过程中的部分信息包括一个唯一的密钥.作为服务的当前要求,它作为审计过程的一部分提供关键唯一性检查.重复密钥违反了流程要求.

目前,该服务将实现为对SQL-Server的写入.虽然不太可能,但密钥可能是重复的,在这种情况下,SqlException会抛出抱怨主键约束违规.我宁愿将此异常包装在更通用的"重复键"异常中,该异常可被捕获,然后允许进程生成新密钥.

通常,我讨厌创建一个新的异常类; 几乎总有一种合适的类型可用于传达相同的信息.我已经抓住了System.Data.Linq.DuplicateKeyException过去,它看起来像是一个很好的候选者,除了它来自LINQ相关的命名空间,我的界面与LINQ无关.

我的直接选择似乎是:

  • System.Data.Linq.DuplicateKeyException无论如何都要扔,希望没有人过多地读入命名空间.
  • 抛出System.InvalidOperationException并交叉我的手指我从来不需要一个可以因其他原因抛出此异常的实现.
  • 抛出我自己的习惯DuplicateKeyException.
  • 在接口中创建一个单独的方法来检查密钥唯一性,并在写入密钥和值之前调用它.

你对此有何看法?

Ant*_*nes 5

重用另一个命名空间中的异常 有时我会借用基本.NET框架中存在的异常,但我认为应该绘制线条.个人进入LINQ命名空间只是为了重复使用异常跨越那一行,我不会这样做.

使用InvalidOperationException 如果看起来不太可能需要特别捕获异常的原因,那么这是一个合理的使用方法.这不是这里的情况,所以我也不会这样做.

使用自定义DuplicateKeyException 这是有道理的.这样的异常可能是捕获的候选者,因为代码很可能能够对它做些什么.例外来自您的命名空间,您可以添加其他相关详细信息以帮助进行异常处理.

添加"IsUnique"方法 如果在调用"IsUnique"和WriteAction方法之间键不再是唯一的,比如由于另一个线程改变了什么,会发生什么?这种方法可能很有用,因为没有代码可能依赖于抛出的异常来检测它(这将是一件坏事).但是,如果在WriteAction上,键仍然不是唯一的,那么你仍然需要创建一个异常,不能保证接口的使用者首先会调用"IsUnique"方法.