2013-01-18 22 views
7

Ho una matrice di strutture. L'operatore foreach esegue una copia di ciascun elemento durante l'iterazione attraverso un array? Per quanto ho capito foreach è appena zucchero sintattico sotto la cappa convertita in for. Quindi sembra che la risposta sia no ma mi piacerebbe avere qualche conferma.Foreach copia ogni elemento se è un array di strutture?

PS: sembra che qualcuno dovrebbe averlo già chiesto ma non trovo facilmente nulla. Quindi, vota come un duplicato con un riferimento fornito.

+0

Vuoi sapere se foreach fa una copia della variabile di riferimento? Esempio: foreach (IPAddress ips in IPList) La variabile di riferimento qui è ips. – Botonomous

risposta

8

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).

+0

Quindi, in altre parole, qualunque cosa io usi, non importa. Grazie! Ora, quando penso a dopo aver letto quali problemi hanno le persone con le strutture e 'foreach', penso di capire perché. Le strutture sono tipi di valore. In caso di degenerazione, ad esempio di usare 'int', difficilmente si riesce a copiare il suo valore nello stack. Quindi anche la struttura viene copiata. Grazie ancora - è innegabilmente la risposta più completa. – Schultz9999

+0

Non necessariamente. Se si utilizza un ciclo 'for' e si accede alla matrice per indice, non sarà necessario creare copie. In tal caso verrà utilizzata l'istruzione 'ldelema', ma' ldobj' (la parte che copia il valore nello stack) potrebbe non esserlo, a seconda di cosa stai facendo con l'istanza. – cdhowie

+0

Ma pensavo avessi detto che avrebbe usato l'accesso all'array ... – Schultz9999

Problemi correlati