合同.确保和异常处理

本文关键字:异常处理 确保 合同 | 更新日期: 2023-09-27 18:36:01

我最近发现了.NET Contract API,虽然我不喜欢使用方法而不是扩展语法的实现方式(在我看来,Sing#做对了),但我更喜欢使用它们而不是旧的/常规方式使用if's进行,例如null检查。

我也即将接近我的第一个合同。确保调用,我偶然发现了一个问题,我们将如何在包含协定的方法中处理异常。确保在运行时遇到异常?

合同这个词。确保感觉我必须处理方法中的异常并使我的类再次进入正确的状态,但是如果我不能呢?

假设我们这里有这个类:

public class PluginManager
{
    private ILoadedFromAtCompileTimeUnknownAssembly extension;
    public bool IsFinished { get; private set; }
    public void Finish()
    {
        extension.Finish();
        this.IsFinished = true;
    }
}

我们可以使用 Contract.Assure 来确保在方法完成后 IsDone 为真吗?

合同.确保和异常处理

是的。确保基本上意味着"确保方法是否正常终止",即没有例外。

我发现很难正确理解代码契约的概念。代码协定旨在查找编程错误。如果以这种方式应用,则可以删除发布版本的协定,并且应用程序将继续完美运行。

但是很难将编程(又称逻辑错误)与配置和输入数据问题区分开来。这些检查必须保留在发布版本中。因此,使用代码协定来检查扩展/插件是否正确加载是一个坏主意,因为它通常配置到您的应用程序中。如果删除发布版本中的协定,则会获得应用程序的不同行为,具体取决于在调试或发布版本中配置的应用是否错误。

仅报告一种异常类型的合同违规,这使得无法在应用程序的上层做出反应,例如应用程序中的配置问题或逻辑错误。对于 react 我并不是要继续,而是向用户/开发人员提供一条远程有用的消息,出了什么问题。

代码契约在表面上看起来不错,但我担心大多数人以错误的方式使用它。它并不意味着替换方法中输入验证的所有 null 检查。您应该仅将 null 检查的方法替换为代码协定,其中您确定逻辑问题而不是输入数据是根本原因。

如果您希望控制台应用程序中的文件名作为输入,而用户确实忘记在命令行中提供文件名,那么用 ContracException 问候用户不是一个好主意。

  • 该错误消息会让用户感到困惑。
  • 您无法将编程错误与用户输入验证问题区分开来。
  • 您无法捕获任何特定的合同异常,因为异常类型是内部的。

请参阅用户文档。

7.6 合约异常 ContractException 类型不是公共类型,而是作为嵌套私有类型发出到每个程序集中,这些程序集 运行时协定检查已启用。因此不可能写 捕获处理程序仅捕获合同异常。合同例外 因此,只能作为一般异常支持的一部分进行处理。这 此设计的基本原理是程序不应包含控件 依赖于合约失败的逻辑,就像程序不应该一样 捕获 ArgumentNullException 或类似的验证异常。