简体   繁体   English

ReSharper警告 - 访问修改后的关闭

[英]ReSharper Warning - Access to Modified Closure

I have the following code: 我有以下代码:

string acctStatus = account.AccountStatus.ToString();
if (!SettableStatuses().Any(status => status == acctStatus))
    acctStatus = ACCOUNTSTATUS.Pending.ToString();

Note that account.AccountStatus is an enum of type ACCOUNTSTATUS. 请注意,account.AccountStatus是ACCOUNTSTATUS类型的枚举。 On the second line, ReSharper is giving me the warning "Access to Modified Closure" for acctStatus. 在第二行,ReSharper向我发出了acctStatus的“访问修改后的关闭”的警告。 When I do the recommended operation, Copy to local variable , it modifies the code to the following: 当我执行建议的操作, 复制到本地变量时 ,它将代码修改为以下内容:

string acctStatus = realAccount.AccountStatus.ToString();
string s = acctStatus;
if (!SettableStatuses().Any(status => status == s))
    acctStatus = ACCOUNTSTATUS.Pending.ToString();

Why is this better or preferable to what I had originally? 为什么这比我原来的更好或更好?

EDIT 编辑

It also recommends Wrap local variable in array , which produces: 它还建议在数组中包装局部变量 ,它产生:

string[] acctStatus = {realAccount.AccountStatus.ToString()};
if (!SettableStatuses().Any(status => status == acctStatus[0]))
    acctStatus[0] = ACCOUNTSTATUS.Pending.ToString();

This seems downright wacky to me. 这对我来说似乎很奇怪。

The reason for the warning is that inside a loop you might be accessing a variable that is changing. 警告的原因是在循环内部您可能正在访问正在更改的变量。 However, the "fix" isn't really doing anything for you in this non-loop context. 但是,在这种非循环上下文中,“修复”并没有真正为您做任何事情。

Imagine that you had a FOR loop and the if was inside it and the string declaration was outside it. 想象一下,你有一个FOR循环,if在里面,字符串声明在它之外。 In that case the error would be correctly identifying the problem of grabbing a reference to something unstable. 在这种情况下,错误将正确地识别抓取对不稳定的东西的引用的问题。

An example of what you don't want: 你不想要的一个例子:

string acctStatus

foreach(...)
{
  acctStatus = account.AccountStatus[...].ToString();
  if (!SettableStatuses().Any(status => status == acctStatus))
      acctStatus = ACCOUNTSTATUS.Pending.ToString();
}

The problem is that the closure will grab a reference to acctStatus, but each loop iteration will change that value. 问题是闭包会获取对acctStatus的引用,但每次循环迭代都会改变该值。 In that case it would be better: 那种情况下会更好:

foreach(...)
{
  string acctStatus = account.AccountStatus[...].ToString();
  if (!SettableStatuses().Any(status => status == acctStatus))
      acctStatus = ACCOUNTSTATUS.Pending.ToString();
}

As the variable's context is the loop, a new instance will be created each time because we have moved the variable inside the local context (the for loop). 由于变量的上下文是循环,因此每次都会创建一个新实例,因为我们已将变量移动到本地上下文(for循环)中。

The recommendation sounds like a bug in Resharper's parsing of that code. 这个建议听起来像是Resharper解析该代码的一个错误。 However, in many cases this is a valid concern (such as the first example, where the reference is changing despite its capture in a closure). 但是,在许多情况下,这是一个有效的问题(例如第一个例子,尽管它在闭包中被捕获,但引用正在改变)。

My rule of thumb is, when in doubt make a local. 我的经验法则是,如果有疑问,那就是当地人。

Here is a real world example I was bitten by: 这是一个我被咬过的真实世界的例子:

        menu.MenuItems.Clear();
        HistoryItem[] crumbs = policyTree.Crumbs.GetCrumbs(nodeType);

        for (int i = crumbs.Length - 1; i > -1; i--) //Run through items backwards.
        {
            HistoryItem crumb = crumbs[i];
            NodeType type = nodeType; //Local to capture type.
            MenuItem menuItem = new MenuItem(crumb.MenuText);
            menuItem.Click += (s, e) => NavigateToRecord(crumb.ItemGuid, type);
            menu.MenuItems.Add(menuItem);
        }

Note that I capture the NodeType type local, note nodeType, and HistoryItem crumb.ItemGuid, not crumbs[i].ItemGuid. 请注意,我捕获NodeType类型local,note nodeType和HistoryItem crumb.ItemGuid,而不是crumbs [i] .ItemGuid。 This ensures that my closure will not have references to items that will change. 这可以确保我的闭包不会引用将要更改的项。

Prior to using the locals, the events would trigger with the current values, not the captured values I expected. 在使用本地之前,事件将使用当前值触发,而不是我预期的捕获值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM