C# 如果每个元素是一个结构数组,foreach会复制它吗?
我有一个结构数组。在遍历数组时,C# 如果每个元素是一个结构数组,foreach会复制它吗?,c#,.net,C#,.net,我有一个结构数组。在遍历数组时,foreach操作符是否复制每个元素?据我所知,foreach只是将语法糖转换为for。看来答案是否定的,但我想确认一下 PS:看来应该有人已经问过了,但我找不到任何东西。因此,请以提供参考的dup身份投票。是的,将制作值类型实例的副本。当在数组上迭代时,foreach确实会使用数组访问,而不是使用枚举数,但每个数组槽中的值仍会被复制 此代码: struct AStruct { public string a; public int b;
foreach
操作符是否复制每个元素?据我所知,foreach
只是将语法糖转换为for
。看来答案是否定的,但我想确认一下
PS:看来应该有人已经问过了,但我找不到任何东西。因此,请以提供参考的dup身份投票。是的,将制作值类型实例的副本。当在数组上迭代时,
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
中)。您想知道foreach是否复制到参考变量吗?示例:这里的foreach(IPList中的IPAddressIPS)引用变量是ips。所以换句话说,无论我使用哪一个,都不重要。谢谢现在,当我阅读完structs和foreach
后思考人们在使用时遇到了什么问题时,我想我明白了原因。结构是值类型。在退化情况下,例如,使用int
几乎没有办法不将其值复制到堆栈中。因此,结构也被复制。不过,再次感谢你——不可否认,这是最完整的答案。不一定。如果使用for
循环并按索引访问数组,则不一定要创建副本。在这种情况下,将使用ldelema
指令,但ldobj
(将值复制到堆栈上的部分)可能不会,这取决于您对实例所做的操作。@Schultz9999它使用直接数组访问将数组中的每个值复制到迭代变量x
。我的意思是,这与使用枚举器对象和IEnumerator.Current
访问值不同。在这两种情况下,都将复制该值。(但要复制的值将通过较少的间接级别获得。)让我们