2011-10-18 20 views
8

posible duplicado:
C# parameters by reference and .net garbage collectionelementos de la matriz de ref

Yo estaba pensando en usar argumentos árbitro para limitar las corrientes de los límites matriz. Por ejemplo, el código de intercambio de dos elementos es:

class Test { 
    int[] array; 

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

que tiene 4 acceso a la matriz será la alternativa:

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; 
    } 
} 

que teóricamente sólo tiene 2 acceso a la matriz

Lo que me confunde es que no sé qué ocurre exactamente cuando paso un elemento de matriz por ref. Si el recolector de basura inicia, mientras ejecuta el código en la función Intercambiar, ¿podrá mover la matriz? o la matriz se fija para la duración de la llamada?

Tenga en cuenta que el código anterior es un caso de prueba simple. Quiero utilizarlo en escenarios mucho más complejos

Edit: Como BrokenGlass señaló, esto es contestada por Eric Lippert aquí C# parameters by reference and .net garbage collection

La matriz no se inmovilizó y GCollector puede moverlo y actualizará accordinly cualquier ref a un elemento de la misma, que reside en la pila

+2

No intente optimizar de forma prematura, * especialmente * si no tiene un conocimiento profundo de cómo funciona la maquinaria. Caso en cuestión: su segunda versión (con 'ref') en realidad será * mucho * más lenta que la primera debido al boxeo (pruébelo en un bucle y vea). – Jon

+4

@Jon, estoy de acuerdo en que probablemente no tenga sentido hacer esto por razones de rendimiento, pero mejora la legibilidad ... Y por cierto, no hay boxeo en ese caso –

+0

Panos, agregó un GC.Collect() para enfatizar el punto , retrocede si no te gusta. –

Respuesta

0

la pila podría tener este aspecto:

  • qsort() tiene una referencia a la matriz
  • Intercambiar()

Entonces, si GC.Collect() se ejecuta en swap, todavía hay una referencia a la matriz en qSort() lo que significa que no se recopilará.

0

La función Swap sigue accediendo a la matriz 3 o 4 veces, la función Intercambiar no ofrece ninguna ventaja sobre el código más simple. Puede ser útil si se reutiliza.

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 
} 

El recolector de basura no liberará memoria que tiene una referencia a, como sucede cuando se pasa por referencia.