`
beefcow
  • 浏览: 44629 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
最近访客 更多访客>>
社区版块
存档分类
最新评论

Cannot refer to a non-final variable i inside an inner class defined in a differ

阅读更多

涉及到闭包(closure)的概念。

 

不同语言对闭包选择了不同的支持,相比之下,C#中就能够在匿名函数中引用非final的外部变量,例如这篇帖子中提到的C#代码:

List<Func<int>> actions = new List<Func<int>>();

int variable = 0;
while (variable < 5)
{
    actions.Add(() => variable * 2);
    ++ variable;
}

foreach (var act in actions)
{
    Console.WriteLine(act.Invoke());
}

这一行:

actions.Add(() => variable * 2);

就在匿名方法内引用了外部局部变量: variable.

 

但同时也引起了一个奇怪的问题,上面的C#代码,我们期望的结果应该是输出"0, 2, 4, 6, 8"才对,结果却是10个零。

 

原因就是C# compiler 在所闭的包内圈入了对variable的引用,然后当运行

Console.WriteLine(act.Invoke());

时,variable值已经变成5,结果输出为10个零。

 

这种特性多少有点令人意外,可能java正是为了避免这种情形,于是强制规定闭包内引用的外部局部变量必须为final,想象一下如果上例中variable 为final的话,自然就不会写出上面的代码,造成类似的意外了。

 

另外,上例中如果你希望达到输出"0, 2, 4, 6, 8"的效果,可以:

while (variable < 5)
{
    int copy = variable;
    actions.Add(() => copy * 2);
    ++ variable;
}

 

 

ps.参考了很多文章,理解也仍然算不上透彻,列举在下,供包括自己的后来人参考

 

  http://stackoverflow.com/questions/5997953/cannot-refer-to-a-non-final-variable-i-inside-an-inner-class-defined-in-a-differe

  http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-different

  http://stackoverflow.com/questions/271440/c-captured-variable-in-loop

  http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/what-are-closures.aspx

  http://csharpindepth.com/Articles/Chapter5/Closures.aspx

  http://en.wikipedia.org/wiki/Closure_(computer_science)

  http://zh.wikipedia.org/wiki/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6)

0
1
分享到:
评论

相关推荐

    NVMe-over-Fabrics-1.1-2019.10.22-Ratified.pdf

    The mapping of extensions defined in this document to a specific NVMe Transport are defined in an NVMe Transport binding specification. This document contains an NVMe Transport binding specification ...

    Refer a Friend 2014-Spring Special Scheme

    ### Refer a Friend 2014-Spring Special Scheme 概览 #### 方案背景与目标 - **方案名称**:“Refer a Friend 2014-Spring Special Scheme” - **方案时间**:2014年2月至2014年4月30日 - **活动覆盖范围**:适用...

    Turbo C++ 3.0[DISK]

    If you want to run such hosted EXEs in a Windows Standard Mode DOS window, you should run DPMIRES.EXE before loading Windows. To do this, enter the following commands at DOS: set DPMIMEM=MAXMEM ...

    Turbo C++ 3.00[DISK]

    If you want to run such hosted EXEs in a Windows Standard Mode DOS window, you should run DPMIRES.EXE before loading Windows. To do this, enter the following commands at DOS: set DPMIMEM=MAXMEM ...

    2009 达内Unix学习笔记

    id -a root 显示用户所在组的所有组名(如root用户,是所有组的组员) df 查看文件系统,查看数据区 用法 df [-F FSType] [-abeghklntVvZ] [-o FSType 特定选项] [目录 | 块设备 | 资源] df -k 以kbytes显示文件...

    高中英语 知识点大全10 8refer torefer…to

    【高中英语知识点详解:refer to / refer…to】 在学习英语的过程中,掌握各种动词的用法至关重要。本文将详细解析“refer to”和“refer…to”这两个短语的含义和用法。 1. “refer to”通常作为不及物动词使用,...

    Refer-it-in-RGBD:CVPR 2021中我们的论文“在Refer-it-in-RGBD中”​​的资料库

    引用到RGBD 这是CVPR 2021中论文“在RGBD中... 我们通过与从ScanRefer数据集和我们新收集的SUN-Refer数据集提取的RGB-D图像上的最新技术进行比较,来评估所提出的方法。 实验表明,在两个数据集上,我们的方法都比以前

    Chinese Entity Linking Comprehensive

    referred to in each query has a matching entity node in the reference Knowledge Base (KB) (LDC2014T16). If there is a matching node for a query, annotators create a link between the two. If there is ...

    傅立叶快速变换算法实例源码

    The commercial license allows you to include the compiled code in a product or to use the code on a regular basis. You are however NOT allowed to sell the source code. Distribution of the ...

    Embedded.Systems.Introduction

    An embedded system is a system that performs a specific task and has a computer embedded inside. A system is comprised of components and interfaces connected together for a common purpose. This book ...

    java面试题英文版及其答案

    Method overriding allows a subclass to provide a different implementation for a method defined in its superclass, while method overloading involves having multiple methods with the same name but ...

    DevExpress VCL 13.1.4(v2013vol1.4) 源码-例子-帮助-part2

    Q513198 - Moving focus to TcxDBSpinEdit placed in TdxBarControlContainerItem does not fire the OnExit and OnEnter events and, as a result, does not fire the OnGetText event of a dataset field bound to...

    DevExpress VCL 13.1.4(v2013vol1.4) 源码-例子-帮助-part1

    Q513198 - Moving focus to TcxDBSpinEdit placed in TdxBarControlContainerItem does not fire the OnExit and OnEnter events and, as a result, does not fire the OnGetText event of a dataset field bound to...

    数位板压力测试

    This specification was developed in response to a perceived need for a standardized programming inter-face to digitizing tablets, three dimensional position sensors, and other pointing devices by a ...

    DevExpress VCL 13.2.5 D7-DXE6 FullSource

    •S173543 - Introduce a property providing access to the FNewLoadMode field declared in the TcxCustomVerticalGrid class Common Libraries ExpressEditors Library •S173677 - Documentation - Add a note...

    NVM-Express-1_4a-2020.03.09-Ratified.pdf

    The NVM ExpressTM (NVMeTM) interface allows host software to communicate with a non-volatile memory subsystem. This interface is optimized for Enterprise and Client solid state drives, typically ...

    Turbo C 2.00[DISK]

    static variable or a variable that is local to a static function. o Because of the limited memory available in the Tiny model, it no longer supports graphics functions. o The Version 1.5 ...

    BobBuilder_app

    I deferred from testing the get test over 100 million record as it would require a huge array in memory to store the Guid keys for finding later, that is why there is a NT (not tested) in the table. ...

    微软内部资料-SQL性能优化2

    A reference to an invalid page (a page that is not in your working set) is referred to as a page fault. Assuming the page reference does not result in an access violation, a page fault can be either ...

Global site tag (gtag.js) - Google Analytics