如果无法加载预期的注册表设置,最合适的.NET异常是什么?

时间:2008-12-15 16:18:19

标签: c# .net

我有一个应用程序试图在其构造函数中加载一些预期的注册表设置。

如果无法加载这些(必要的,非默认的)注册表设置,那么从BCL抛出的最合适的.NET异常是什么?

例如:

 RegistryKey registryKey = Registry.LocalMachine.OpenSubkey("HKLM\Foo\Bar\Baz");

 // registryKey might be null!
 if (registryKey == null)
 {
     // What exception to throw?
     throw new ???Exception("Could not load settings from HKLM\foo\bar\baz.");
 }

9 个答案:

答案 0 :(得分:14)

为什么不创建自定义例外?

public class KeyNotFoundException : RegistryException
{
    public KeyNotFoundException(string message)
        : base(message) { }
}
public class RegistryException : Exception
{
    public RegistryException(string message)
        : base(message) { }
}

....

if (registryKey == null)
{
    throw new KeyNotFoundException("Could not load settings from HKLM\foo\bar\baz.");
}

此外,您可以继承自Exception,而不是继承自ApplicationException。这取决于您希望应用程序在这种情况下出现的故障类型。

答案 1 :(得分:8)

实际上,我不会在这里抛出异常。我将有一个默认值,然后使用该默认值创建密钥。

如果你必须有一个用户定义的值,我会使用ArgumentException(因为那基本上是你所缺少的,你的构造函数的一个参数 - 你存储它的地方与你所遇到的异常类型无关)试图生成)。

答案 2 :(得分:5)

我会选择ArgumentExceptionArgumentOutOfRangeException ..

throw new ArgumentException("Could not find registry key: " + theKey);

引用MSDN:

  

一个引发的异常   提供给方法的参数   无效。

...

IMO撰写正确的异常消息更为重要。

答案 3 :(得分:2)

这取决于它失败的原因。如果这是权限问题,我会选择System.UnauthorizedAccess例外:

  

操作系统因I / O错误或特定类型的安全错误而拒绝访问时引发的异常。

我不知道它是否与“特定类型”匹配,但这是一个安全错误,并且未授权访问。

另一方面,如果该项目不存在,那么我会抛出FileNotFound异常。当然,注册表项不是文件,但FileNotFound非常清楚。

答案 4 :(得分:2)

由于此条目与您的基本值相同,如果无法获得此值,对您的应用程序的影响是什么?您是否需要进行操作,或者只是需要通知应用程序。

此外,有许多原因导致该值为null

  • 用户无权阅读密钥
  • 密钥不存在

这是否会影响您在处理应用程序时所采取的操作?

我认为这些类型的场景会抛出什么异常。就个人而言,我永远不会抛出异常,因为它实际上是标准设计实践中的“禁忌”。

如果是由于用户没有权限,并且没有此权限可能会导致将来出现问题,我会投票支持UnauthroizedAccess异常。

如果问题不是一个关键问题,但你真的需要知道密钥不在那里,我强烈推荐其他地方提到的“KeyNotFoundException”实现。

当抛出异常时,您希望确保抛出的异常是描述性的并提供所有需要的信息,因此我认为这取决于根本原因以及对应用程序的整体影响。

答案 5 :(得分:2)

引用MSDN的“开发类库的设计指南”

  

<强> ApplicationException的

     

如果您正在设计应用程序   需要创建自己的   例外情况,建议您派生   异常中的自定义异常   类。原本以为是这样的   自定义异常应来自   ApplicationException类;   但实际上并没有这样做   发现增加了重要的价值。对于   更多信息,请参阅最佳实践   处理例外。

答案 6 :(得分:1)

我认为最好的方法是退后一步。如果没有描述正在发生的事情的明确异常,则只需几分钟即可定义一个异常。尽量避免重新利用异常,因为它“足够接近”。

我的建议是你应该创建一个继承自Exception或ApplicationException的基类异常类。这将允许您从堆栈跟踪中轻松识别异常是您定义的自定义异常还是源自其他位置的异常。所有自定义异常都应该从您创建的基本异常继承。

注意:我不建议使用Exception或ApplicationException。社区与微软的文档之间存在足够的争论,应该使用哪些文档以及用于何种目的。在个人层面上,我选择Exception作为我的基本例外。

如果没有与您的意图匹配的明确预定义的异常,则继续从您的基本异常中派生自定义异常。它肯定有助于追踪问题的根源,使它们更容易处理(想象一下现有的框架异常被抛入代码块,但是通过框架或其他方法),并且只是简单明了。

请记住,您可以将多个异常层次结构组合在一起,例如异常。例如,我可以拥有继承ApplicationException或Exception的MyBaseException。然后我可以有一个更通用的MyRegsitryException,它继承自MyBaseException。然后我可以有特定的异常,例如MyRegistryKeyNotFoundException或MyRegistryKeyPermissionException。

这允许您在更高级别捕获分组异常,并减少可能包含冗余处理机制的捕获数量。将此与将异常范围隔离到将使用它们的特定命名空间相结合,您就可以开始使用非常干净的异常处理方案。

答案 7 :(得分:0)

我可能会抛出一个ApplicationException,因为它与您的应用程序特别相关。或者,您可以抛出ConfigurationErrorsException,但这通常与解析应用程序配置文件时出错,而不是从注册表中读取配置。

我想到的其他潜在异常是ArgumentException或ArgumentNullException,但它们的内涵与传递给方法的参数有关,因此不适合我的想法。在尝试确定代码无法正常工作时,它很容易导致某人使用/修改代码误入歧途。

在任何情况下,良好的描述性错误消息可能是沟通问题的最有效方式。

编辑:请注意,在空值上抛出异常不会屏蔽尝试读取注册表值时发生的任何异常。我相信,只要你不将它包装在try / catch块中,当你试图在没有足够权限的情况下读取值时抛出的任何SecurityException都会发生。

答案 8 :(得分:-3)

我认为Exception本身可以完成这项工作。如果您的信息足够描述,那么一切都很好。如果你真的想要准确,那么我同意petr k。滚动你自己。