gpt4 book ai didi

c# - ReSharper 警告 - 访问修改后的闭包

转载 作者:IT王子 更新时间:2023-10-29 04:02:42 26 4
gpt4 key购买 nike

我有以下代码:

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();

为什么这比我原来的更好或更可取?

编辑

它还建议在数组中包装局部变量,它会产生:

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

这对我来说似乎很古怪。

最佳答案

警告的原因是在循环内您可能正在访问正在更改的变量。但是,在这个非循环上下文中,“修复”并没有真正为您做任何事情。

想象一下,您有一个 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。这确保我的闭包不会引用将要更改的项目。

在使用本地变量之前,事件会以当前值触发,而不是我预期的捕获值。

关于c# - ReSharper 警告 - 访问修改后的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1688465/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com