gpt4 book ai didi

c# - 为什么每个循环输出 10? int不是值类型吗?

转载 作者:太空宇宙 更新时间:2023-11-03 19:44:50 24 4
gpt4 key购买 nike

我浏览了一些 C# 示例并发现了这个:

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
class Program
{
delegate void Printer();

static void Main()
{
List<Printer> printers = new List<Printer>();

for (int i = 0; i < 10; i++)
{
printers.Add(delegate { var d = i; Console.WriteLine(d); });
}

foreach (var printer in printers)
{
printer();
}
Console.ReadLine();
}
}
}

我希望它输出 09,因为 int 是一个值类型,d 应该设置为当时 i 的值。

但是,这会输出 10 十次。

这是为什么? int 不是引用而是在委托(delegate)内部吗?

注意:我并不想在这里解决问题,只是理解它是如何工作的,以一种可重复应用的方式。

编辑:我的困惑示例

int i = 9;
int d = 8;
d = i;
i++;
Console.WriteLine(d);

这表明 i 是作为值而不是引用传递的。我在闭包内部期望相同,但感到惊讶。


感谢您的评论,我现在了解得更多了,委托(delegate)中的代码直到之后才执行,它使用 i 存在于它之外的编译器创建的泛型类中?

在 javascript 中,这种相同类型的代码输出 1-9,这正是我在 C# 中所期望的。 https://jsfiddle.net/L21xLaq0/2/ .

最佳答案

您可能有兴趣查看此代码实际上是如何被编译器重写的,因为它有助于理解正在发生的事情。如果你编译然后在一些反编译器(如 dotPeek)中查看 dll 并禁用“花哨的 View ”,你会看到这个(一些名称被更改因为它们不可读):

class Program {
delegate void Printer();

private static void Main() {
List<Program.Printer> printerList = new List<Program.Printer>();
// closure object which holds captured variables
Program.DisplayClass10 cDisplayClass10 = new Program.DisplayClass10();
int i;
// loop assigns field of closure object
for (cDisplayClass10.i = 0; cDisplayClass10.i < 10; cDisplayClass10.i = i + 1) {
// your delegate is method of closure object
printerList.Add(new Program.Printer(cDisplayClass10.CrypticFunctionName));
i = cDisplayClass10.i;
}
// here, cDisplayClass10.i is 10
foreach (Program.Printer printer in printerList)
printer();
Console.ReadLine();
}

// class for closure object
[CompilerGenerated]
private sealed class DisplayClass10 {
public int i;

internal void CrypticFunctionName() {
Console.WriteLine(this.i);
}
}
}

关于c# - 为什么每个循环输出 10? int不是值类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47360168/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com