gpt4 book ai didi

c# - 这段代码是防御性编程,还是不好的做法?

转载 作者:IT王子 更新时间:2023-10-29 04:38:47 25 4
gpt4 key购买 nike

关闭。这个问题是opinion-based .它目前不接受答案。












想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题.

4年前关闭。




Improve this question




我和我的同事就这段代码进行了辩论:

var y = null;
if (x.parent != null)
y = x.parent.somefield;

我的观点是,在代码所在的地方, x.parent不应该为空。当它为空时,我们有一个严重的问题,我想知道它!因此,不应该进行空检查并让下游异常发生。

我的同事说这是防御性编程。并且空检查确保代码不会破坏应用程序。

我的问题是,这是防御性编程吗?还是不好的做法?

注意:重点不在于谁是对的。我正在尝试从这个例子中学习。

最佳答案

有趣的问题。在我看来,是否包含检查取决于数据的验证程度、数据来自何处以及检查失败时会发生什么。

“x.parent 不应该为空”是一个严肃的假设。你需要非常确定它才能安全,当然还有经典的“它永远不会发生”......直到它发生,这就是为什么我认为回顾这些可能性很有趣。

我看到两件不同的事情需要考虑。

数据来自哪里?

  • 如果它来自同一个类中的另一个方法,或来自某个相关类,因为您或多或少可以完全控制它,那么放松防御是合乎逻辑的,因为您可以合理地假设它不太可能有坏数据开始使用,或者如果它发生了,在调试/测试期间早期捕获错误甚至对其进行一些单元测试是相当容易的。
  • 相反的情况是,如果它是用户输入的数据,或者从文件中读取的数据,或者从 URL 中读取的数据,一般来说是外部的任何内容。由于您无法控制程序正在处理的内容:无论如何,请在以任何方式使用它之前尽可能彻底地验证它,因为您会接触到可能导致问题的虚假/丢失/不完整/不正确/恶意信息路径。
  • 中间情况可能是输入来自同一系统内的另一个层/层。更难决定是进行全面验证还是将其视为理所当然,因为它是另一个内部软件,但可能会在以后单独替换或修改。我更喜欢在跨越边界时再次验证。

  • 如何处理验证?
  • 使用 if (如在您的示例中)在某些情况下,简单地跳过某些分配或用法可能没问题。例如,如果用户正在输入一些数据并且这只是显示工具提示或其他次要信息,则跳过可能是安全的。但是如果这段代码做了一些重要的事情,反过来又填充了一些强制条件或执行了一些其他进程,这不是正确的方法,因为它会导致下一次代码运行出现问题。问题是,当您跳过某些代码时,这样做必须是安全的,没有任何副作用或不需要的后果,否则您将隐藏一些错误,并且在以后的开发阶段很难调试。
  • 优雅地中止当前过程是早期验证的一个不错选择,当失败是完全可以预料的并且您确切地知道如何响应它时。一个例子可能是缺少必填字段,过程被中断,并向用户显示一条消息,询问缺少的信息。简单地忽略错误是不行的,而且还不够严重到引发破坏正常程序流程的异常。当然,您可能仍会使用异常,具体取决于您的架构,但无论如何都要捕获它并优雅地恢复。
  • 当“不可能”真的发生时,抛出异常总是一种选择。在这种情况下,您无法为继续某些变化或仅取消当前流程提供合理的响应,这可能是由于某个地方的错误或错误输入,但重要的是您想知道它并拥有关于它的所有细节,所以最好的方法是让它尽可能大声地爆炸,这样异常就会冒泡并到达一个中断一切的全局处理程序,保存到日志文件/数据库/任何东西,发送一个向您报告崩溃并找到恢复执行的方法(如果可行或安全)。至少如果您的应用程序崩溃,请以最优雅的方式进行,并留下痕迹以供进一步分析。

  • 与往常一样,这取决于情况。但是仅仅使用 if 来避免编写异常处理程序肯定是一种不好的做法。它必须始终存在,然后一些代码可能会依赖它——无论是否合适——如果它不是关键的失败。

    关于c# - 这段代码是防御性编程,还是不好的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22239274/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com