gpt4 book ai didi

c# - "Access to modified closure"是否通过理解语法解析?

转载 作者:可可西里 更新时间:2023-11-01 08:54:07 26 4
gpt4 key购买 nike

ReSharper 6.0 为第一个代码片段中的 dr 标识符发出“访问修改后的闭包”警告。

private IEnumerable<string> GetTheDataTableStrings(DataTable dt) {
foreach (DataRow dr in dt.Rows) {
yield return GetStringFuncOutput(() => dr.ToString());
}
}

我想我对这个警告试图保护我的内容有一个基本的了解:dr 在询问 GetTheDataTableStrings 的输出之前更改了几次,因此调用者可能无法获得我的输出/行为期待。

但是对于第二个代码片段,R# 没有给我任何警告。

private IEnumerable<string> GetTheDataTableStrings(DataTable dt) {
return from DataRow dr in dt.Rows select GetStringFuncOutput(dr.ToString);
}

在使用理解语法时放弃这个警告/问题对我来说安全吗?

其他代码:

string GetStringFuncOutput(Func<string> stringFunc) {
return stringFunc();
}

最佳答案

首先,您对第一个版本的关注是正确的。该 lambda 创建的每个委托(delegate)都对 相同 变量关闭,因此随着该变量的变化,查询的含义也会发生变化。

其次,仅供引用,我们很可能会在下一版本的 C# 中修复此问题;这是开发者的一大痛点。

(更新:这个答案写于 2011 年。事实上,我们确实在 C# 5 中进行了下面描述的修复。)

在下一个版本中,每次运行“foreach”循环时,我们都会生成一个循环变量,而不是每次都关闭同一个变量。这是一个“重大”更改,但在绝大多数情况下,“重大”更改将用于修复而不是导致错误。

“for”循环不会改变。

参见 http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/了解详情。

第三,查询理解版本没有问题,因为没有被修改的封闭变量。查询理解形式与您所说的相同:

return dt.Rows.Select(dr=>GetStringFuncOutput(dr.ToString));

lambda 不封闭任何外部变量,因此不会意外修改变量。

关于c# - "Access to modified closure"是否通过理解语法解析?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8649337/

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