当我在Visual Studio(2008)内部发现静态验证警告时,我只是在堆栈溢出中回答某人的问题:
string[] source = { "1", "A", "B" };
var sourceObjects = Array.ConvertAll(source, c => new Source(c)).ToArray();
我收到消息需要未经证实的来源!= null 。我觉得很明显,事实并非如此。这只是一个例子。另一方面,一些漂亮的东西似乎运作得相当好。
我正在使用1.2.20518.12版本(5月18日)。我发现代码合同非常有趣,但有没有其他人有这样的案例?您是否认为当前的实施在实践中是可行的,或者您认为它们在这一点上纯粹是学术性的?
我已将其设为社区维基,但我想听听一些意见:)
答案 0 :(得分:16)
如果你分开两个电话会更有意义:
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
var sourceObjects = tmp.ToArray();
现在它指向 last 行作为问题。换句话说,对Array.ConvertAll
的调用知道源不为空,但对ToArray()
的调用不知道tmp
不会为空。
(由于在您的源代码中使用了名称source
,您的示例也有些混乱 - 即使您将变量调用完全不同,错误仍会使用source
,如它指的是Enumerable.ToArray
中的第一个参数。)
基本上我相信当Array.ConvertAll获得适当的非nullity后置条件时,这一切都会起作用。在那之前,这将解决问题:
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
Contract.Assume(tmp != null);
var sourceObjects = tmp.ToArray();
我同意这种事情很烦人,但我确信随着MS在BCL中增加越来越多的合同,它会迅速改善。重要的是要注意静态检查器本身的不问题。
(事实上,Array.ConvertAll
也没有先决条件 - 如果您在上面的第二个代码段中将source
变量设置为null,它仍然不会抱怨。)