6

我致力于开发外部 API。我在公共接口中添加了一个方法:

public void AddMode(TypeA mode);
public void AddMode(TypeB mode); // the new method, TypeB and TypeA are not related at all

看起来不错,直到有一个测试通过了null. 这使编译器与模棱两可的调用混淆。我通过强制转换为空来修复测试。

但是我的问题是:

  • 我应该仅仅因为这个而改变名字吗?
  • 还是应该让客户像我一样做演员?(如果他们因任何原因通过 null)

在设计 API 时,在这种情况下最好的是什么?

编辑

调用就像这样AddMode(null),而不是:

TypeA vl = null; 
AddMode(v1); // this doesn't cause a problem
4

5 回答 5

6

一个 API 应该被设计成易于正确使用和难以错误使用。您的 API 易于正确使用:

AddMode(new TypeA());

编译。

使用不当更难:

AddMode(null);

不编译。用户被迫做类似的事情

AddMode((TypeA)null);

这应该让他思考,这是否是预期的用法。所以我认为你的 API 没问题。

于 2012-06-26T09:43:02.430 回答
1

我认为这取决于null各自论点的价值有多特殊。

例如,比较这个ArgumentNullException构造函数:当必须设置内部异常时最常调用它。否则,将传递除非法参数名称之外的这个构造函数。在奇怪的情况下,必须调用前者,因为必须提供自定义消息,但不提供内部异常(我通常在为包含null但不是null自身的数组/集合参数抛出异常时这样做)。所以,在这种情况下,我需要明确的演员表,我会说这是可以接受的。

如果你的方法确实做同样的事情,但null仍然是一个通常的值,你可能想为null变体添加一个无参数重载(即显式转换仍然是可能的,但用户也可以调用无参数重载)。

如果您的方法做了一些不同的事情,nullnullnull.

更新:如果null无论如何都是不可接受的(并且会导致异常),那么您应该保持该方法不变。除了出于测试目的之外,任何情况下都不应该将文字null传递给方法,因为这总是会产生异常。因此,在这种情况下不要更改您的重载名称。

于 2012-06-26T09:29:32.013 回答
0

无论如何,此方法的 null 有效输入是否有效?

就我个人而言,只要 AddMode 的两个重载都相关,我就会保留它,因为您希望 AddMode(X) 和 AddMode(Y) 做一些彼此相关的事情。

如果它们没有任何关系,那么可能需要更改方法名称

于 2012-06-26T09:30:05.637 回答
0

好吧,这取决于任何一个值在您的 API 中null都是可接受的值。

如果不只是不接受它,不支持它。因此,即使消费者尝试将其与null编译器一起使用,也会因歧义问题而中断。

于 2012-06-26T09:31:23.117 回答
0

如果您的 API 接受 null 作为可能的参数值,那么您必须在文档中指定它并提及有必要强制转换它,并编写一些代码示例来说明如何。

但是,如果您不希望用户使用 null 值,则可以将 TypeA 和 TypeB 更改为 astruct而不是 a class,如果您的类设计允许的话。

于 2012-06-26T09:42:55.977 回答