为啥要存储对 int (而不是值)的“引用”? [复制]
Posted
技术标签:
【中文标题】为啥要存储对 int (而不是值)的“引用”? [复制]【英文标题】:Why is "reference" to an int (and not value) stored? [duplicate]为什么要存储对 int (而不是值)的“引用”? [复制] 【发布时间】:2017-09-15 09:01:05 【问题描述】:下面的代码sn-p会输出数字'10'十次:
delegate void Printer();
static void Main()
List<Printer> printers = new List<Printer>();
for (int i = 0; i < 10; i++)
printers.Add(delegate Console.WriteLine(i); );
foreach (var printer in printers)
printer();
这是因为(取自https://www.toptal.com/c-sharp/interview-questions#iquestion-90455):
" 委托被添加到 for 循环中,并且存储了对 i 的“引用”, 而不是价值本身。因此,在我们退出循环后, 变量 i 已设置为 10,所以到每个委托时 调用时,传递给它们的值都是 10。”
我的问题是:为什么会存储对 i 的“引用”?
【问题讨论】:
【参考方案1】:这不是按值与按引用的影响。
输出为 10,因为变量 i
的值是在第二个循环中的委托代码运行时评估的,到那时将假定值 10,因为那是当第一个循环退出时,结果是什么。
使用调试器在第二个循环中单步执行对printer()
的调用,您会发现委托闭包在调用时的原始作用域中采用i
的值。
【讨论】:
不应该是i
在循环外不可用
@EpicKip 是的。请参阅我在答案中链接的博客文章。
见:blogs.msdn.microsoft.com/ericlippert/2009/11/12/… & blogs.msdn.microsoft.com/ericlippert/2009/11/16/…【参考方案2】:
这是因为“在 for 循环中添加了委托,并且存储了对 i 的“引用”
不,这不是问题。问题在于提取委托和引用值的方式。这叫做闭包。委托是从循环中提取的,并且只保留i
的最后一个值,因为闭包是在 循环之后运行的。 (如果中途调用它,它会返回当时的值)。
请参阅 this blog post 委托最终是如何在看似错误的地方编译的。
这是它用来演示问题的代码:
Func func1 = null;
Program.<>c__DisplayClass2 class1 = new Program.<>c__DisplayClass2(); // <-- problem
class1.i = 0;
while (class1.i < count)
if (func1 == null) // <-- more problems to follow
func1 = new Func(class1.<fillFunc>b__0); // <-- yikes: just one func!
Program.funcArr[class1.i] = func1;
class1.i++; // <-- and just one i
【讨论】:
根据blogs.msdn.microsoft.com/ericlippert/2009/11/12/…用较新的C#版本,这个问题不存在了吗?以上是关于为啥要存储对 int (而不是值)的“引用”? [复制]的主要内容,如果未能解决你的问题,请参考以下文章