Sì, verranno create copie delle istanze del tipo di valore. Durante l'iterazione su un array, foreach
utilizza effettivamente gli accessi di matrice invece di utilizzare un enumeratore, ma il valore in ogni slot di matrice viene comunque copiato.
Questo codice:
struct AStruct
{
public string a;
public int b;
static void Main()
{
var structs = new AStruct[10];
foreach (var x in structs) {
Console.WriteLine(x);
}
}
}
genera il seguente IL per il metodo Main()
:
.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
Nota le istruzioni IL_0013 attraverso IL_001d. L'intero valore in ogni slot dell'array viene inserito nello stack e memorizzato nel V_3 locale (la variabile di iterazione x
).
Vuoi sapere se foreach fa una copia della variabile di riferimento? Esempio: foreach (IPAddress ips in IPList) La variabile di riferimento qui è ips. – Botonomous