做出一致的 API,有什么不足为奇的?

Making a consistent API, what's less surprising?

我有一个 API,其中有 属性 个访问器,例如:

int foo()

有时属性可以是 "null"。由于 int 不能为 null,因此使用额外的 属性 来处理以检查 null。

bool hasFoo()

当 foo() 为 null 时人们调用它会发生什么? foo() 的实现在内部检查 hasFoo() 和恐慌,而不是具有未定义的行为,这通常会终止线程或进程并显示错误消息。

花车让事情变得更有趣。此 API 中的浮点数具有空值:NaN。所以对于

float bar()

当 hasBar() returns 为 false 时,bar 将始终 return NaN,这是定义明确的行为。事实上,大多数类型、字符串、日期等都有有效的 "null" 表示。整数和布尔是奇数,其中 0 可以是有效值。

所以我的问题是,当 hasBar() 为 false 时 bar() 是否也应该 panic 以与 ints 和 bools 保持一致?或者可能是 int 和 bool 在它们为 null 时应该 return 0,并且只有调用 hasFoo() 才能区分真正的 0 和 null 0。什么行为不那么令人惊讶?为什么?

如果 API 是 return 可空值,作为开发人员,我最希望 return 类型是可空的,如果语言支持的话(https://msdn.microsoft.com/en-us/library/1t3y8s4s.aspx)

按照这些思路,如果您希望常规用例中有很多空值,那么最好创建一个 returned 的包装器响应对象,类似于此伪代码示例:

public class Response<T>()
{
    bool HasValue { get; }
    T Value { get; }
}

因此,使用这种方法,您将 return Response < int > 而不是 int 和 Response < float > 而不是 float ...等等。

情况 1:当 hasBar() 为 false 时 bar() 也出现 panic

这对我来说并不奇怪,就好像我没有为浮点数分配任何东西一样,我不应该期待 return 形式的任何东西。返回 NaN 是一种避免程序异常并让它完成它正在尝试做的事情的便捷方法,但如果您正在设计自己的实现方式,这就不足为奇了。但这会带来其他问题,因为您必须捕获抛出的每个异常并以某种优雅的方式处理。

情况2:只有调用hasFoo()才能区分真实0和空0

这肯定会令人惊讶,因为并不是每个人都知道他们需要检查另一个值来验证它是否为实际 0,但您将在这里优雅地处理异常。