如何解决ReSharper警告-访问修改后的闭包
警告的原因是,在循环内您可能正在访问一个正在更改的变量。但是,在这种非循环上下文中,“修复”并没有真正为您做任何事情。
假设您有一个FOR循环,而if循环位于其中,而字符串声明位于其外部。在那种情况下,错误将正确地识别出获取不稳定对象引用的问题。
您不想要的示例:
string acctStatus
foreach(...)
{
acctStatus = account.AccountStatus[...].ToString();
if (!SettableStatuses().Any(status => status == acctStatus))
acctStatus = ACCOUNTSTATUS.Pending.ToString();
}
问题在于闭包将获取对acctStatus的引用,但是每次循环迭代都会更改该值。在 这种 情况下,最好:
foreach(...)
{
string acctStatus = account.AccountStatus[...].ToString();
if (!SettableStatuses().Any(status => status == acctStatus))
acctStatus = ACCOUNTSTATUS.Pending.ToString();
}
由于变量的上下文是循环,因此每次都会创建一个新实例,因为我们已经将变量移到了本地上下文中(for循环)。
该建议听起来像是Resharper解析该代码中的错误。但是,在许多情况下,这是一个值得关注的问题(例如第一个示例,尽管引用已在闭包中捕获,但引用仍在更改)。
我的经验法则是,如果有疑问,请在当地定居。
这是一个我被咬过的真实例子:
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);
}
请注意,我捕获的是本地的NodeType类型,请注意nodeType和HistoryItem crumb.ItemGuid,而不是crumbs [i] .ItemGuid。这确保了我的关闭不会引用将要更改的项目。
在使用本地变量之前,事件将使用当前值而不是我期望的捕获值触发。
解决方法
我有以下代码:
string acctStatus = account.AccountStatus.ToString();
if (!SettableStatuses().Any(status => status == acctStatus))
acctStatus = ACCOUNTSTATUS.Pending.ToString();
请注意,account.AccountStatus是ACCOUNTSTATUS类型的枚举。在第二行,ReSharper向我发出acctStatus的警告“访问已修改的闭包”。当我执行建议的操作时,
复制到本地变量 ,它将代码修改为以下内容:
string acctStatus = realAccount.AccountStatus.ToString();
string s = acctStatus;
if (!SettableStatuses().Any(status => status == s))
acctStatus = ACCOUNTSTATUS.Pending.ToString();
为什么这比我原来的更好或更可取?
编辑
它还建议 将局部变量包装在array中 ,这会产生:
string[] acctStatus = {realAccount.AccountStatus.ToString()};
if (!SettableStatuses().Any(status => status == acctStatus[0]))
acctStatus[0] = ACCOUNTSTATUS.Pending.ToString();
这对我来说似乎很古怪。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。