访问修改后的闭包,这是 ReSharper 的 bug 吗?

发布于 2024-08-27 23:15:26 字数 680 浏览 8 评论 0原文

我有最新的 ReSharper 5.0 版本 (1655),我在以下代码中遇到了“访问修改后的闭包”的建议:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>();
dates.Where(d => d > now);
...
now = new DateTime();

并且 lambda 表达式内的 now 带有警告下划线。

我很确定这是 ReSharper 的错误,但真的是这样吗?

编辑:我应该更好地检查,代码稍后有一个对 now 的分配。

编辑2乔恩·斯基特的answer 几乎回答了这个问题,但是下面的呢:

var query = dates.Where(d => d > now).ToList();

这不应该通过立即执行查询来解决问题吗?

I have the latest ReSharper 5.0 build (1655), where I have encountered the suggestion 'Access to modified closure' on the following code:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>();
dates.Where(d => d > now);
...
now = new DateTime();

and the now inside the lambda expression is underlined with the warning.

I'm pretty sure that's a ReSharper bug, but is it really?

EDIT: I should have checked better, there was an assignment to now later in the code.

EDIT 2 Jon Skeet's answer below pretty much answers this, but what about the following:

var query = dates.Where(d => d > now).ToList();

Shouldn't this solve the problem by executing the query immediately?

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

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

发布评论

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

评论(3

凑诗 2024-09-03 23:15:26

好吧,现在你已经修改了问题,这完全有道理。您正在修改闭包中使用的变量 - 这可能会产生意外结果:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>();
var query = dates.Where(d => d > now);
...
now = new DateTime(1990, 1, 1);
foreach (DateTime date in query)
{
    // This will only see dates after 1990, not after 1970
    // This would confuse many developers.
}

事实上,这不仅仅是查询何时开始的问题 - 您可以在迭代结果时修改它:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>();
var query = dates.Where(d => d > now);
...
foreach (DateTime date in query)
{
    now = date;
    Console.WriteLine(date);
}

这将给出严格递增的日期序列...再次,有点令人困惑。

在我看来,R# 对此提出警告是绝对正确的。它有时很有用 - 但应该非常小心地使用。

Right, now you've modified the question, it makes complete sense. You're modifying a variable used within a closure - which can produce unexpected results:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>();
var query = dates.Where(d => d > now);
...
now = new DateTime(1990, 1, 1);
foreach (DateTime date in query)
{
    // This will only see dates after 1990, not after 1970
    // This would confuse many developers.
}

In fact, it's not just a matter of when the query starts - you could modify it while iterating over the results:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>();
var query = dates.Where(d => d > now);
...
foreach (DateTime date in query)
{
    now = date;
    Console.WriteLine(date);
}

That will give a strictly-increasing sequence of dates... again, somewhat confusing.

R# is absolutely right to warn about this, IMO. It can sometimes be useful - but should be used with great care.

〃安静 2024-09-03 23:15:26

ReSharper 警告您的是,now 的值正在 lambda 表达式中捕获,而不是您认为执行 lambda 时的值。

要解决您的问题,您需要在使用之前将 now 的值分配给局部变量:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>{new DateTime(2001, 12, 12)};
DateTime localNow = now;
dates.Where(d => d > localNow);

now = new DateTime(2003, 12, 12);

如果您想了解更多信息,ReSharper 论坛有一个 帖子 其中包括几个带有进一步解释的链接。

What ReSharper is warning you about is that the value of now is being captured in the lambda expression and is not the value you think it is when the lambda gets executed.

To solve your problem, you need to assign the value of now to a local variable before you use it:

var now = new DateTime(1970, 1, 1);
var dates = new List<DateTime>{new DateTime(2001, 12, 12)};
DateTime localNow = now;
dates.Where(d => d > localNow);

now = new DateTime(2003, 12, 12);

If you want to read more, the ReSharper forum has a post on it which includes several links with further explanation.

写下不归期 2024-09-03 23:15:26

不,这是重新思考您在循环遍历集合时修改集合的内容,很可能是日期。您可以放心地忽略这一点。

No this is resharper thinking you are modifying the contents of a collection while looping over it, dates most probably. You can safely ignore this.

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