当前位置: 首页 > 编程语言 > C#

Closurecapturevariablesalsomodifyoriginalvariables分享

时间:2023-04-10 12:28:29 C#

Closurecapturevariablesalsomodifiedoriginalvariables我有以下简单代码:staticvoidMain(string[]args){intj=0;Funcf=()=>{for(inti=0;i<3;i++){j+=i;返回j;};intmyStr=f();控制台.WriteLine(myStr);控制台.WriteLine(j);控制台.Read();从我读到的关于闭包的内容来看,编译器创建了一个新类型,以便它可以存储捕获的变量并维护对它的引用。但是,当我运行以下代码时,两条打印行显示3。我期待0和3,因为匿名方法在生成的类中由编译器拥有自己的变量。那么它为什么要修改外部变量呢?外层变量和闭包中的变量是同一个变量。你的程序等价于:privateclassClosure{publicintj;publicintMethod(){for(inti=0;if=closure.Method;intmyStr=f();Console.WriteLine(myStr);Console.WriteLine(closure.j);Console.Read();}现在很明显为什么你会被观察到?这就是闭包的工作方式,它们捕获变量,而不是值。所以j将被改变。如果你不想那样,你可以这样做:staticvoidMain(string[]args){intj=0;Funcf=()=>{intk=j;for(inti=0;ij仍然被闭包捕获,但没有被修改。只有副本k被修改。编辑:你正确地注意到这对引用类型不起作用。在那种情况下,k=j存储对象引用的副本。仍然存在引用对象的副本,因此对该对象的任何修改的引用都会影响这两个变量。下面是一个如何在不更新原始变量的情况下将闭包用作引用类型的示例:staticvoidMain(string[]args){Fooj=newFoo(0);Funcf=()=>{Fookk=newFoo(jN);//不能只说k=j;for(inti=0;i但是,字符串是不可变的引用类型,您实际上可以说k=j,这与任意引用类型不同。考虑不可变性的一种方法是,每次更新字符串的值时,您实际上创建一个新实例。所以k=k+"1"就像说k=newString(k+"1")。此时,它不再是对与j相同的字符串的引用。语言规范说:匿名方法类似于Lisp编程语言中的lambda函数。C#2.0支持创建“闭包”,其中匿名方法访问周围的局部变量和参数。在你的情况下,'j'是周围的变量。以上是C#学习教程:捕获变量的Closure也会修改原变量分享的全部内容,如果对大家有用,需要详细了解C#学习教程,希望大家多多关注——本文收藏来自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处: