我有一个调用Action<string>
public Action<string> DisplayError;
public void MyMethod()
{
DisplayError("ERROR");
}
在这个方法中我想调用DisplayError但是我可以看到,如果DisplayError为null,它将抛出异常。
我可以运行一个测试,证明它会抛出异常。
所以我知道我想在我的代码中添加if (DisplayError != null)
,但我觉得这个设计在某种程度上是错误的。也许测试应该有所不同?
答案 0 :(得分:1)
这完全取决于背景。
此类的用户是否需要根据合约设置值?然后它应该抛出异常。
可选吗?那么你的检查是有效的,但是如果你只是将DisplayError
默认为一个空的Action,你会得到类似的行为
DisplayError = s => {};
您的方法还可能会导致用户将 DisplayError
设置为null
,在这种情况下,只有您可以决定什么是有效的。如果您将其设置为属性而不是字段,您将为自己提供更多选项。
_displayError = s => {};
public Action<string> DisplayError
{
get { return _displayError; }
set
{
_displayError = value ?? (s => {});
/* or throw on null */
}
}
答案 1 :(得分:1)
不要将Action设为公共字段,而是将其设为属性或将其传递给方法。然后,您可以在该点进行空检查。我也怀疑你需要在设置之后检索它,所以:
_displayError = (s) => { throw new ArgumentNullException("Please tell me what to do with this exception!"); };
public Action<string> DisplayError
{
set
{
if (value == null) { throw new ArgumentNullException("I need this!"); }
_displayError = value;
}
}
public void MyMethod()
{
_displayError("ERROR");
}
或者:
public void MyMethod(Action<string> displayError)
{
if (displayError == null) { throw new ArgumentNullException("I need this!"); }
displayError("ERROR");
}
其中第一个不应要求消费者更改代码。
当然,如果您只是与使用代码的团队合作,那么根本不需要进行空检查。只需找出谁错误地使用您的代码并进行友好聊天,以找出误解的位置。防御性编程不是一个很好的替代成员相互信任的团队,而且无效检查不如拥有明确定义,易于使用的界面那么有效。
您需要进行2次测试:
我的课程:
答案 2 :(得分:0)
我相信在Steve Yeggie的一次谈话中,我听到了这一点:有些东西可以说'虽然静态类型的语言在编译时确实可以保护你免受各种错误的影响,但它们并没有否定空检查'。
我觉得这很正常。
我只是在喝早晨的咖啡,所以如果我完全错过了这个标记,请告诉我。