访问修改后的闭包 - 为啥这是一个建议的修复?

Posted

技术标签:

【中文标题】访问修改后的闭包 - 为啥这是一个建议的修复?【英文标题】:Access to Modified Closure - why is this a suggested fix?访问修改后的闭包 - 为什么这是一个建议的修复? 【发布时间】:2017-04-24 03:57:04 【问题描述】:

所以我有这样的代码:

int totalRequestsToSend = 0;
i = 1;

foreach (file in files)

    try
    
        // This can throw if adding request fails for some reason, e.g. file does not exist
        requests.AddRequest(
            new FileStoreRequest(file)
            
                OnStoreConfirm = (file) =>
                
                    progress.Report((i*100)/totalRequestsToSend)
                    Interlocked.Increment(ref i);
                
            
            );
        totalRequestsToSend += 1;
    
    catch(Exception e) 
        // handle exception
    

Resharper 抱怨“访问修改后的闭包”关于我在 lambda 中使用 totalRequestsToSend 的行。

逻辑按预期工作,可以忽略投诉,但是,Resharper 建议的修复之一将 int 变量更改为大小为 1 的数组,如下所示:

int[] totalRequestsToSend = 0;
i = 1;

foreach (file in files)

    try
    
        requests.AddRequest(
            new FileStoreRequest(file)
            
                OnStoreConfirm = (file) =>
                
                    progress.Report((i*100)/totalRequestsToSend[0])
                    Interlocked.Increment(ref i);
                
            
            );
        totalRequestsToSend[0] += 1;
    
    catch(Exception e) 
        // handle exception
    

这不会引起 Resharper 的投诉。我很困惑。在这种情况下,使用数组与使用变量有何不同?

谢谢。

【问题讨论】:

看答案here @Jonesopolis 这并没有说明封闭的变量被包装在一个数组中,或者为什么 resharper 会建议这样的重构。请注意,在这种情况下,需要访问已修改的闭包;这不是无意使用它。 @Servy 我确实做了一些让你生气的事情。如果您不再跳过我,我什至无法提供可能添加一些上下文的链接。这是一条试图提供帮助的评论。 @Jonesopolis,谢谢。这并不能完全解决我的问题,但它确实让我相信这个建议在 Resharper 中被打破了 【参考方案1】:

没有什么不同。重构没有任何成果。

【讨论】:

以上是关于访问修改后的闭包 - 为啥这是一个建议的修复?的主要内容,如果未能解决你的问题,请参考以下文章

访问修改后的闭包 (2)

访问修改后的闭包:ReSharper

Javascript:为啥访问闭包变量可能很慢

如何升级到 C# 5.0?访问修改后的闭包

Do.. While.. 使用 Exists 谓词。访问修改后的闭包?

如何修复:在闭包 resharper 警告中访问 foreach 变量?