如果是结构体数组,foreach是否复制每个元素

本文关键字:复制 元素 是否 foreach 结构体 数组 如果 | 更新日期: 2023-09-27 17:54:49

我有一个结构体数组。在迭代数组时,foreach操作符是否复制每个元素?据我所知,foreach只是语法糖在引擎盖下转换成for。所以答案似乎是否定的,但我想得到一些确认。

PS:似乎有人已经问过了,但我找不到任何东西。因此,请在提供参考的情况下投票。

如果是结构体数组,foreach是否复制每个元素

是的,将复制值类型实例。当在数组上迭代时,foreach确实会使用数组访问而不是使用枚举器,但每个数组槽中的值仍然被复制。

这个代码:

struct AStruct
{
    public string a;
    public int b;
    static void Main()
    {
        var structs = new AStruct[10];
        foreach (var x in structs) {
            Console.WriteLine(x);
        }
    }
}

Main()方法生成以下IL:

.method private static hidebysig
       default void Main ()  cil managed
{
    .entrypoint
    .maxstack 4
    .locals init (
            valuetype AStruct[]     V_0,
            valuetype AStruct[]     V_1,
            int32   V_2,
            valuetype AStruct       V_3)
    IL_0000:  ldc.i4.s 0x0a
    IL_0002:  newarr AStruct
    IL_0007:  stloc.0
    IL_0008:  ldloc.0
    IL_0009:  stloc.1
    IL_000a:  ldc.i4.0
    IL_000b:  stloc.2
    IL_000c:  br IL_002d
    IL_0011:  ldloc.1
    IL_0012:  ldloc.2
    IL_0013:  ldelema AStruct
    IL_0018:  ldobj AStruct
    IL_001d:  stloc.3
    IL_001e:  ldloc.3
    IL_001f:  box AStruct
    IL_0024:  call void class [mscorlib]System.Console::WriteLine(object)
    IL_0029:  ldloc.2
    IL_002a:  ldc.i4.1
    IL_002b:  add
    IL_002c:  stloc.2
    IL_002d:  ldloc.2
    IL_002e:  ldloc.1
    IL_002f:  ldlen
    IL_0030:  conv.i4
    IL_0031:  blt IL_0011
    IL_0036:  ret
} // end of method AStruct::Main

注意IL_0013到IL_001d的指令。每个数组槽的整个值被压入堆栈并存储在本地V_3 (x迭代变量)中。