我致力于开发外部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
答案 0 :(得分:6)
API的设计应使其易于正确使用且难以正确使用。 您的API易于正确使用:
AddMode(new TypeA());
编译。
使用不正确更难:
AddMode(null);
无法编译。用户不得不做类似
的事情AddMode((TypeA)null);
这应该让他想一想,这是否是预期用途。所以我认为你的API没问题。
答案 1 :(得分:1)
我认为这取决于异常null
作为相应参数的值是多少。
比较,例如,this ArgumentNullException
constructor:当必须设置内部异常时,最常调用它。否则,除了非法参数名称之外的this constructor将被传递。在奇怪的情况下,前者必须被调用,因为必须提供自定义消息,但是没有提供内部异常(当我为包含null
的数组/集合参数抛出异常时,我通常会这样做,但不是null
本身。因此,在这种情况下,我需要明确的演员表,我会说它在那里是可以接受的。
如果您的方法确实相同,但null
仍然是常用值,您可能希望为null
变体添加无参数重载(即显式转换仍然可以,但用户也可以调用无参数过载。)
如果你的方法做了某些不同的事情,而null
还有其它方法,那么你可以考虑完全禁用null
所显示的方法,并为{{1}添加无参数重载案件。
更新:如果null
无论如何都不可接受(并且会导致异常),那么您应该保留原样。除了用于测试目的之外,永远不应该存在文字null
将被传递给方法的任何情况,因为这将不可避免地产生异常。因此,在这种情况下不要更改重载名称。
答案 2 :(得分:0)
无论如何,此方法是否为null有效输入?
就个人而言,只要AddMode的两个重载都相关,我就会保持原样,因为你希望AddMode(X)和AddMode(Y)做一些彼此相关的事情。
如果它们没有任何关联,那么可能会按顺序更改方法名称
答案 3 :(得分:0)
嗯,这取决于您的API中null
值是可接受的值。
如果不是不接受它,不支持它。因此,即使消费者尝试将其与null
一起使用,编译器也会打破歧义问题。
答案 4 :(得分:0)
如果您的API接受null作为可能的参数值,那么您必须在文档中指定它并提及有必要进行转换,并编写一些代码示例来说明如何。
但是,如果您不希望用户使用空值,则可以将TypeA和TypeB更改为struct
而不是class
,如果您的类设计允许的话。