IS"获得修改封"通过理解语法解决? [英] Is "Access to modified closure" resolved by comprehension syntax?

查看:146
本文介绍了IS"获得修改封"通过理解语法解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ReSharper的6.0给了我获得修改封闭的警示为博士标识符中的第一个代码片段。



<预类=郎-CS prettyprint-覆盖> 私人的IEnumerable<串GT; GetTheDataTableStrings(数据表DT){
的foreach(DataRow的博士在dt.Rows){
收率返回GetStringFuncOutput(()=> dr.ToString());
}
}



我觉得我有什么这个警告的基本理解试图保护我。博士修改几次被询问GetTheDataTableStrings的输出之前,因此调用者可能无法得到输出/行为我期待



但R·不给我第二个代码片段的任何警告。



<预类=郎-CS prettyprint-覆盖> 私人的IEnumerable<串GT; GetTheDataTableStrings(数据表DT)从dt.Rows的DataRow医生{
返回选择GetStringFuncOutput(dr.ToString);
}

是否安全对我来说,用理解语法时,丢弃此警告/关注?



其他代码:



<预类=郎-CS prettyprint-覆盖> 字符串GetStringFuncOutput(Func键<串GT; stringFunc){
返回stringFunc();
}


解决方案

首先,你是正确的需关注的第一个版本。由拉姆达创建的每个委托过的相同的变量封闭的,因此作为变量的变化,查询变化的含义。



二,仅供参考,我们极有可能在C#中的下一个版本来解决这个问题;这是开发商的一大痛点。



在下一版本每次通过foreach循环运行时,我们将生成一个新的的循环变量,而不是关在同一个变量每次。这是一个破的变化,但在绝大多数情况下的破将被修复,而不是导致错误。



在for循环不会改变



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



第三,有与查询理解版本没有问题,因为没有封闭在正被修改的变量。查询理解的形式是一样的,如果你说:

 返回dt.Rows.Select(DR = GT; GetStringFuncOutput (dr.ToString)); 



的拉姆达没有关闭过任何外变量,所以没有变量被意外修改


ReSharper 6.0 gives me the "Access to modified closure" warning for the dr identifier in the first code snippet.

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

I think I have a basic understanding of what this warning is trying to protect me from: dr changes several times before GetTheDataTableStrings's output is interrogated, and so the caller might not get the output/behavior I expect.

But R# doesn't give me any warning for the second code snippet.

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

Is it safe for me to discard this warning/concern when using the comprehension syntax?

Other code:

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

解决方案

First off, you are correct to be concerned about the first version. Each delegate created by that lambda is closed over the same variable and therefore as that variable changes, the meaning of the query changes.

Second, FYI we are highly likely to fix this in the next version of C#; this is a major pain point for developers.

In the next version each time you run through the "foreach" loop we will generate a new loop variable rather than closing over the same variable every time. This is a "breaking" change but in the vast majority of cases the "break" will be fixing rather than causing bugs.

The "for" loop will not be changed.

See http://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/ for details.

Third, there is no problem with the query comprehension version because there is no closed-over variable that is being modified. The query comprehension form is the same as if you'd said:

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

The lambda is not closed over any outer variable, so there is no variable to be modified accidentally.

这篇关于IS&QUOT;获得修改封&QUOT;通过理解语法解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆