.NET 代码契约:还有比这更基础的吗?

发布于 2024-07-30 08:13:32 字数 462 浏览 9 评论 0原文

我只是在 Stack Overflow 上胡乱回答某人的问题,这时我注意到 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 日)。 我发现代码合约非常有趣,但是其他人有这样的案例吗? 您认为当前的实现在实践中可用,还是认为它们目前纯粹是学术性的?

我已将其设为社区维基,但我想听听一些意见:)

I was just messing around to answer someone's question here on Stack Overflow, when I noticed a static verification warning from inside my Visual Studio (2008):

string[] source = { "1", "A", "B" };
var sourceObjects = Array.ConvertAll(source, c => new Source(c)).ToArray();

I'm getting the message requires unproven source != null. It seems pretty obvious to me that this is not the case. This is just one example of course. On the other side, some pretty nifty stuff seems to be working fairly well.

I'm using the 1.2.20518.12 release (May 18th). I find code contracts very interesting, but has anyone else had cases like this? Do you consider the current implementation usable in practice, or would you consider them purely academic at this point?

I've made this a community wiki, but I'd like to hear some opinions :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦情居士 2024-08-06 08:13:32

如果您将这两个调用分开,则更有意义:

string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
var sourceObjects = tmp.ToArray();

现在它指向问题所在的最后一行。 换句话说,对 Array.ConvertAll 的调用知道 source 不为 null,但对 ToArray() 的调用不知道 tmp 不会为空。

(由于在源代码中使用了名称 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();

我同意这种事情很烦人,但我相信随着 MS 在 BCL 中添加越来越多的合同,它会迅速改善。 需要注意的是,这不是静态检查器本身的问题。

(事实上​​,Array.ConvertAll 也没有前提条件 - 如果您在上面的第二个代码片段中将 source 变量设置为 null,它仍然不会抱怨.)

It makes more sense if you split the two calls up:

string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
var sourceObjects = tmp.ToArray();

Now it points to the last line as the problem. In other words, the call to Array.ConvertAll knows that source isn't null, but the call to ToArray() doesn't know that tmp won't be null.

(Your example is also slightly confusing due to the use of the name source in your source code - the error would still use source even if you'd called your variable something completely different, as it's referring to the first parameter in Enumerable.ToArray.)

Basically I believe this would all work when Array.ConvertAll gets an appropriate non-nullity postcondition. Until then, this will do the trick:

string[] source = { "1", "A", "B" };
var tmp = Array.ConvertAll(source, c => new Source(c));
Contract.Assume(tmp != null);
var sourceObjects = tmp.ToArray();

I agree this kind of thing is annoying, but I'm sure it will improve rapidly as MS adds more and more contracts into the BCL. It's important to note that it's not a problem with the static checker itself.

(In fact, Array.ConvertAll doesn't have a precondition either - if you set the source variable to null in the second code snippet above, it still wouldn't complain.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文