如何强制执行空检查?
我正在开展一个大项目,即使有1000个自动化测试和100%代码覆盖率的10个,我们也会得到一些荒谬的错误。 我们得到的大约95%的错误是NullReferenceExceptions。
有没有办法在编译时强制执行空值检查?
除此之外,有没有办法在unit testing中自动执行空值检查而不必自己编写null案例的测试?
您应该查看代码合同 。 静态检查器仅适用于高端VS版本,但这基本上就是您所追求的。
网上有大量资源,
你也可以阅读第二版C#深度代码合约章节的预发布版本 – 免费下载第15章 。 (关于代码合同的最新和最大版本,该章略有过时,但没有什么大的。)
100%的代码覆盖率毫无意义。
这是一种虚假的安全感。
你唯一测量的是你正在执行所有代码行。
不:
- 那些代码行都是应该存在的所有代码行
- 那些代码行正常运行(你在测试所有边缘情况吗?)
例如,如果您处理火灾的程序包含一步“跑出大楼”,那么即使在100%的情况下发生这种情况,也许更好的程序是“提醒消防部门,试图停止火灾,如果所有其他方法都失败了就会用完“。
C#中没有任何内容可以帮助您实现这一点,而无需您专门进入并添加代码,代码合同(.NET 4.0)或特定的IF语句(<4.0)。
这不是技术解决方案,而是社交方案。 在外部代码(另一种方法调用等)以任何方式修改引用类型时,只需在您的环境中使其无法访问引用类型而不检查null。 unit testing不能取代良好的老式代码审查。
有没有办法在编译时强制执行空值检查?
不。 编译器无法确定运行时引用变量是否指向null。
排除null生成语句(集合和返回)也是不够的。 考虑:
public class Customer { public List Orders {get;set;} } //now to use it Customer c = new Customer; Order o = c.Orders.First(); //oops, null ref exception;
防御性编程只能让你到目前为止……也许它更好地捕捉exception并像其他任何一样处理它。
1)我认为, Resharper可以建议您检查代码中的一些关键位置。 例如,它建议添加[null引用检查代码]并在允许时添加它。
试试吧。 当然,如果您需要,它会增加您的体验。
2)在开发应用程序的早期阶段,在代码中使用“Fail Fast”模式(或断言,断言)
这些都不可能与C#3一起使用。你必须使用像Spec#这样的东西…我认为C#4可能有一些内置于其中,但我不确定。
spec#: http : //research.microsoft.com/en-us/projects/specsharp
您不能在编译时进行空检查,因为在编译时对象只是类型,并且仅在运行时将类型转换为具有具体值的实例…此处为null。
也许您应该看看TFS的自定义代码分析签入策略
我可能错了,但我认为FxCop有一条规则建议您在代码中添加空引用检查。 您可以尝试通过该工具运行程序集,看看它有什么用。
查看Gendarme ,它可以在测试后与您的测试一起运行(可能在他们之前,如果您愿意)并且有一些与null
检查相关的规则。 你也可以相当简单地写自己的。
.NET框架希望通过使用!来强制执行编译时空引用检查。 修改。
public void MyMethod(!string cannotBeNull)
但是,我们没有编译时检查。 最好的办法是尽量减少外部调用者传递空值的次数,然后对面向公众的方法强制执行空值检查:
public class ExternalFacing { public void MyMethod(string arg) { if (String.IsNullOrEmpty(arg)) throw new ArgumentNullException(arg); implementationDependency.DoSomething(arg); } } internal class InternalClass { public void DoSomething(string arg) { // shouldn't have to enforce null here. } }
然后将适当的unit testing应用于External类以期望ArgumentNullExceptions。