Parameters 我们应该允许空/空参数吗?

Parameters 我们应该允许空/空参数吗?,parameters,null,code-contracts,Parameters,Null,Code Contracts,我最近与一位同事讨论了是否应该允许null或空集合作为方法参数传递。我的感觉是,这应该引起一个例外,因为它破坏了方法的“契约”,即使它不一定会破坏方法的执行。这也有“快速失败”的优点。我的同事认为,这会导致在代码中乱丢“notnull/notempty”检查,即使这并不重要 我可以理解他的观点,但允许null或空参数让我感到不安。它可以通过延迟失败来隐藏问题的真正原因 让我们举两个具体的例子: 1) 假设我们有一个带有重叠(Interval)方法的Interval类,那么如果将null作为参数传

我最近与一位同事讨论了是否应该允许null或空集合作为方法参数传递。我的感觉是,这应该引起一个例外,因为它破坏了方法的“契约”,即使它不一定会破坏方法的执行。这也有“快速失败”的优点。我的同事认为,这会导致在代码中乱丢“notnull/notempty”检查,即使这并不重要

我可以理解他的观点,但允许null或空参数让我感到不安。它可以通过延迟失败来隐藏问题的真正原因

让我们举两个具体的例子:

1) 假设我们有一个带有重叠(Interval)方法的Interval类,那么如果将null作为参数传递,会发生什么呢?我的感觉是,我们应该抛出一个IllegalArgumentException,让调用者知道可能出了问题,但我的同事觉得返回false就足够了,因为在他使用它的场景中,第二个间隔是否为null并不重要(重要的是它们是否重叠)

2) 给定FetchById(集合ID)这样的方法,如果提供了空集合,会发生什么?我想再次提醒打电话的人,有什么不正常的事情正在发生,但我的同事可以只收到一个空列表,因为他再次不在乎是否有任何ID

被调用代码的责任在哪里结束?在这两种情况下,调用代码并不介意参数是null还是空,但在其他情况下,这可能指向一个可能的bug。一个方法应该只保证只要遵循前提条件,它就不会中断,还是应该尝试识别潜在的错误调用


编辑:我看到了很多好的答案,大多数人倾向于在文档中将其定义为合同/并坚持执行,但我想听听您对何时允许和何时不允许(如果有)的意见。在具体的例子中,你会怎么做?考虑到90%的使用情况,不验证输入就可以了,您是否仍要验证以清除剩余10%中的错误,还是更愿意在出现错误时解决这些问题并避免不必要的空/空检查?

我想这没有对错之分,但当您抛出异常时,这意味着发生了无法预料的事情,您无法从中恢复。例如,一个方法应该将某个内容写入磁盘,而该磁盘已满。。。所以你应该问问自己:有没有一种方法可以解决这个问题而不引发异常。另一个问题是,该类中是否包含此功能

例如,如果您有一个名为PrintList()的方法,并且您有一个可能为null的参数,那么该方法是负责获取列表,然后打印它,还是只打印它?可能应该更改该方法的名称以包含以下职责:GetAndPrintList()


还要问问自己,如果团队中增加了一名新成员,会发生什么:他会发现代码易于理解和阅读,而无需额外的文档吗?

许多主流语言(包括Java、C#和大多数脚本语言)的一个主要缺陷是无法说:“必须在这里传递值!”我模模糊糊地回忆起一次对Hejlsberg的采访,他甚至承认这是他对C#的设计感到遗憾的一件事(在我看来,省略常量是另一场灾难,但我们不要离题)

这是你和你的同事对此事如此焦虑的原因。对此没有解决方案(除非语言设计者能够以某种方式修改补丁)。任何一种选择都需要妥协。一旦你们都意识到了这一点,你们就可以越早放松,只挑选引起最少痛苦的东西


就我而言,我倾向于更强大的契约,即使它们只能在运行时执行,因为这更接近于语言应该提供的不可为null的形式参数的概念。

这确实是一个上下文问题,没有好的答案。我会遵循“惊喜最少”的原则来选择。考虑使用代码的人:

    >P>如果要在内部使用代码,请考虑使用它的团队:他们知道如何处理潜在的异常吗?框架是否允许轻松的异常处理?团队是否使用它?如果您是唯一一个担心此类问题的人,那么最好还是继续使用它并处理空参数/列表

  • 如果你正在构建一个API,你几乎是负责人,但你必须保持一致。如果一些方法允许空参数,而另一些方法不允许,这可能是一个糟糕设计的标志

  • 如果您正在构建一些与UI交互的代码,请确保UI能够将错误细化到可以理解的程度,并确保UI设计师知道预期结果。如果用户列表为空时他们不禁用“发送给用户”按钮,他们应该如何处理


所以,对不起,我认为这里没有正确的方法。至于我,只要有可能,我会选择例外学派。

我的一般做法是不接受空值。空的集合就可以了


这些是一般规则,在某些情况下,违反这些规则是有意义的。在这些情况下,这就是方法文档的用途。方法定义了合同,文档是精细的印刷品。

您的案例是两种不同的情况,很好地符合现实世界:

1) 假设我们有一节课间休息课 使用重叠(间隔)方法, 如果传递了null,会发生什么 作为参数?我的感觉是 我们应该扔一个球 IllegalArgumentException允许 打电话的人知道可能有什么事 错了,但我的同事觉得 返回false就足够了

通过