C# .NET代码契约:它能比这更基本吗?
我正忙着回答某人关于堆栈溢出的问题,这时我注意到Visual Studio(2008)中有一个静态验证警告: 我收到消息需要未经证实的来源!=空。对我来说,情况显然不是这样。当然,这只是一个例子。另一方面,一些相当漂亮的东西似乎工作得相当好 我使用的是1.2.20518.12版本(5月18日)。我觉得代码契约非常有趣,但是还有其他人有过这样的案例吗?你认为当前的实现在实践中是可用的吗?或者你认为他们在这一点上纯粹是学术性的吗?C# .NET代码契约:它能比这更基本吗?,c#,.net,code-contracts,microsoft-contracts,C#,.net,Code Contracts,Microsoft Contracts,我正忙着回答某人关于堆栈溢出的问题,这时我注意到Visual Studio(2008)中有一个静态验证警告: 我收到消息需要未经证实的来源!=空。对我来说,情况显然不是这样。当然,这只是一个例子。另一方面,一些相当漂亮的东西似乎工作得相当好 我使用的是1.2.20518.12版本(5月18日)。我觉得代码契约非常有趣,但是还有其他人有过这样的案例吗?你认为当前的实现在实践中是可用的吗?或者你认为他们在这一点上纯粹是学术性的吗? 我已经把这变成了一个社区维基,但我想听听一些意见:)如果你把两个电话
我已经把这变成了一个社区维基,但我想听听一些意见:)如果你把两个电话分开,会更有意义:
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
var sourceObjects = tmp.ToArray();
现在它指出最后一行是问题所在。换句话说,对Array.ConvertAll
的调用知道source不为null,但对ToArray()
的调用不知道tmp
不为null
(由于在源代码中使用了名称source
,您的示例也有点混乱-即使您将变量称为完全不同的名称,错误仍将使用source
,因为它引用的是Enumerable.ToArray
中的第一个参数)
基本上,我相信当Array.ConvertAll获得适当的非空后置条件时,这一切都会起作用。在那之前,这将起到关键作用:
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
Contract.Assume(tmp != null);
var sourceObjects = tmp.ToArray();
我同意这种事情很烦人,但我相信随着微软在BCL中加入越来越多的合同,这种情况会迅速改善。需要注意的是,静态检查器本身并没有问题
(事实上,
Array.ConvertAll
也没有先决条件-如果您在上面的第二个代码段中将source
变量设置为null,它仍然不会抱怨。)就快到了,是的:)老实说,我对它印象深刻。我还没有深入到内部工作,但是如何为基类库现有版本中已经存在的方法定义前置条件和后置条件呢?我猜他们只是删除了ccrewrite通常在发行版中生成的任何内容?@Thorarin:他们不需要替换现有的程序集-他们可以将契约引用程序集与真实的程序集一起部署。是的,这就是我真正的意思:)
string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
Contract.Assume(tmp != null);
var sourceObjects = tmp.ToArray();