当前位置:  开发笔记 > 编程语言 > 正文

访问Modified Closure

如何解决《访问ModifiedClosure》经验,为你挑选了2个好方法。

在这种情况下,没关系,因为您实际上是循环中执行委托.

但是,如果您要保存委托并稍后使用它,则会发现所有委托在尝试访问文件时都会抛出异常[i] - 它们在代理时捕获变量 i而不是其值创建.

简而言之,它应该被视为潜在的陷阱,但在这种情况下,它不会伤害到你.

有关更复杂的结果,请参见本页底部,其结果是违反直觉的.



1> Jon Skeet..:

在这种情况下,没关系,因为您实际上是循环中执行委托.

但是,如果您要保存委托并稍后使用它,则会发现所有委托在尝试访问文件时都会抛出异常[i] - 它们在代理时捕获变量 i而不是其值创建.

简而言之,它应该被视为潜在的陷阱,但在这种情况下,它不会伤害到你.

有关更复杂的结果,请参见本页底部,其结果是违反直觉的.



2> gerrard00..:

我知道这是一个老问题,但我最近一直在研究闭包,并认为代码示例可能有用.在幕后,编译器生成一个类,表示函数调用的词法闭包.它可能看起来像:

private sealed class Closure
{
    public string[] files;
    public int i;

    public bool YourAnonymousMethod(string name)
    {
        return name.Equals(this.files[this.i]);
    }
}

如上所述,您的函数有效,因为谓词在创建后立即被调用.编译器将生成如下内容:

private string Works()
{
    var closure = new Closure();

    closure.files = new string[3];
    closure.files[0] = "notfoo";
    closure.files[1] = "bar";
    closure.files[2] = "notbaz";

    var arrayToSearch = new string[] { "foo", "bar", "baz" };

    //this works, because the predicates are being executed during the loop
    for (closure.i = 0; closure.i < closure.files.Length; closure.i++)
    {
        if (Array.Exists(arrayToSearch, closure.YourAnonymousMethod))
            return closure.files[closure.i];
    }

    return null;
}

另一方面,如果你要存储然后再调用谓词,你会发现对谓词的每次调用都会在闭包类的同一个实例上调用相同的方法,因此会使用相同的值一世.

推荐阅读
我我檬檬我我186
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有