如何强制执行空检查?

我正在开展一个大项目,即使有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。

我可能错了,但我认为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。