2011-10-18 15 views
8

Eventuali duplicati:
C# parameters by reference and .net garbage collectionPassando elementi di un array di rif

Stavo pensando di utilizzare argomenti ref per limitare i limiti di controllo di un array. Ad esempio, il codice di scambiare due elementi è:

class Test { 
    int[] array; 

    private void qSort() { 
    ...blah... 
    int temp = array[a]; 
    array[a] = array[b]; 
    array[b] = temp; 
    } 
} 

che possiede 4 accesso alla matrice l'alternativa sarà:

class Test { 
    int[] array; 

    private void qSort() { 
    ...blah... 
    Swap(ref array[a], ref array[b]); 
    } 

    static void Swap(ref int a,ref int b) { 
    int temp = a; 
    a=b; 
    GC.Collect(); // suppose this happens 
    b=temp; 
    } 
} 

che ha teoricamente solo 2 accesso alla matrice

Ciò che mi confonde è che non so cosa succede esattamente quando passo un elemento dell'array per ref. Se Garbage Collector prende il via, mentre esegue il codice nella funzione Swap, sarà in grado di spostare l'array? o l'array è bloccato per la durata della chiamata?

mente che il codice di cui sopra è un semplice caso di test. Io voglio usarlo in scenari molto più complessi

Edit: Come BrokenGlass sottolineato, questo si risponde con Eric Lippert qui C# parameters by reference and .net garbage collection

La matrice non verrà bloccato e GCollector possibile spostarlo e aggiornerà accordinly qualsiasi ref ad un elemento di esso, che risiede in pila

+2

Non cercare di ottimizzare prima del previsto, * specialmente * se non si dispone di una profonda conoscenza di come funziona il macchinario. Caso in questione: la tua seconda versione (con 'ref') sarà in realtà * molto * più lenta del primo a causa del pugilato (provalo in loop e vedi). – Jon

+4

@ Jon, sono d'accordo probabilmente non c'è punto nel fare questo per motivi di prestazioni, ma non migliora la leggibilità ... E BTW, non v'è alcuna boxe in questo caso –

+0

Panos, ha aggiunto un GC.Collect() per sottolineare il punto , torna indietro se non ti piace. –

risposta

0

la pila potrebbe essere il seguente:

  • qsort() ha un riferimento alla matrice
  • Swap()

Quindi se GC.Collect() viene eseguito in swap, esiste ancora un riferimento all'array in qSort() che significa che non verrà raccolto.

0

La funzione Swap accede ancora all'array 3 o 4 volte, la funzione Scambia non offre alcun adavantage di prestazioni rispetto al codice più semplice. Potrebbe essere utile se è riutilizzato.

static void Swap(ref int a,ref int b) 
{  
    int temp = a; //<-- Here, a is in the array 
    a=b;   //<-- a and b are in the array 
    b=temp;  //<-- b is in the array 
} 

Il garbage collector non rilascia la memoria si ha una riferimento a, come accade quando si passa da riferimento.