C# 拓展署及;设计建议
我有一个调用C# 拓展署及;设计建议,c#,.net,unit-testing,tdd,C#,.net,Unit Testing,Tdd,我有一个调用操作的方法 公共操作显示错误; 公共方法() { 显示错误(“错误”); } 在这个方法中,我想调用DisplayError,但是我可以看到,如果DisplayError为null,它将抛出一个异常 我可以运行一个测试来证明它会抛出异常 所以我知道我想在我的代码中添加一个if(DisplayError!=null),但我觉得这个设计有点错误。也许测试应该有所不同?我相信是在Steve Yeggie的一次演讲中,我听到了这一点:“虽然静态类型语言确实可以在编译时保护您免受各种错误的影
操作的方法
公共操作显示错误;
公共方法()
{
显示错误(“错误”);
}
在这个方法中,我想调用DisplayError,但是我可以看到,如果DisplayError为null,它将抛出一个异常
我可以运行一个测试来证明它会抛出异常
所以我知道我想在我的代码中添加一个
if(DisplayError!=null)
,但我觉得这个设计有点错误。也许测试应该有所不同?我相信是在Steve Yeggie的一次演讲中,我听到了这一点:“虽然静态类型语言确实可以在编译时保护您免受各种错误的影响,但它们并不否定空检查的需要。”
我觉得这很正常
我正在喝早上的咖啡,所以如果我完全没有注意到,请告诉我。这完全取决于上下文 此类的用户是否需要根据合同设置值?然后它应该抛出一个异常 它是可选的吗?那么您的检查是有效的,但是如果您只是将默认的
DisplayError
设置为空操作,您将得到类似的行为
DisplayError = s => {};
您的方法还可能导致用户可以将DisplayError
设置为null
,在这种情况下,只有您可以决定什么是有效的。如果将其设置为属性而不是字段,则会为自己提供更多选项
_displayError = s => {};
public Action<string> DisplayError
{
get { return _displayError; }
set
{
_displayError = value ?? (s => {});
/* or throw on null */
}
}
\u displayError=s=>{};
公共行动显示错误
{
获取{return\u displayError;}
设置
{
_displayError=值??(s=>{});
/*或者抛出空值*/
}
}
与其将操作设置为公共字段,不如将其设置为属性或将其传递到方法中。然后可以在该点执行空检查。我还怀疑您是否需要在设置后检索它,因此:
_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");
}
\u displayError=(s)=>{抛出新的ArgumentNullException(“请告诉我如何处理此异常!”);};
公共行动显示错误
{
设置
{
如果(value==null){抛出新的ArgumentNullException(“我需要这个!”);}
_显示错误=值;
}
}
公共方法()
{
_显示错误(“错误”);
}
或:
public void MyMethod(操作显示错误)
{
如果(displayError==null){抛出新的ArgumentNullException(“我需要这个!”);}
显示错误(“错误”);
}
其中的第一项不需要用户对代码进行任何更改
当然,如果您只是与使用您的代码的团队一起工作,那么您根本不需要进行空检查。只要找出谁把你的代码用错了,然后友好地聊一聊,找出误解所在。防御性编程不是团队成员相互信任的好替代品,空检查也不如拥有一个定义明确、易于使用的界面那么有效
您需要进行两项测试:
我的班级:
- 应允许使用者处理任何错误
- 给定,无论出于何种原因,我都将产生一个错误(在此处设置上下文)
- 当我产生错误时(调用该方法,让错误处理程序设置一些变量)
- 然后我应该将错误提供给处理程序(检查设置的变量)
- 应确保附加了错误处理程序
- 假设我可能会产生一个错误(您可以在这里编写您喜欢的代码,因为它与此无关)
- 当使用者在没有错误处理程序的情况下调用我时(使用null错误处理程序调用该方法)
- 然后我应该立即要求消费者不要这样做(检查例外情况)
_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");
}