none
Carga de datos en una Lista - C# RRS feed

  • Pregunta

  • Estoy trabajando en C#, me resultó un inconveniente algo extraño...

    for (int i = 1; i <= dataRng.Rows.Count; i++)
    {
             for (int j = 1; j <= dataRng.Columns.Count; j++)
             {
                        resultTemp[j - 1] = Convert.ToInt32((dataRng.Cells[i, j] as Excel.Range).Value);
                        if (resultTemp[j - 1] > numNodos)
                            numNodos = resultTemp[j - 1];
              }
              allResults.Add(resultTemp);
    }

    Estoy utilizando un arreglo temporal 1x2 (resultTemp)en el cual estoy cargando unos datos desde Excel y luego, cada vez que cargo una fila completa, lo almaceno en una lista (allResults), el proceso lo repito varias veces para tener una lista con N arreglos, el problema es que al final, los N arreglos en la lista quedan con los mismos valores (De la última fila). Al revisar, haciendo la depuración paso a paso, veo que cada vez que modifico el arreglo temporal, automáticamente se actualizan todas las entradas anteriores en la lista... Pareciera que la lista funcionara sólo como una especie de Pointer (Recordando C). Sé que este no es el funcionamiento normal de las listas porque ya he utilizado en otros casos similares sin este inconveniente. Cualquier idea sería apreciada.


    Alexánder Cumbal

    jueves, 21 de agosto de 2014 20:58

Respuestas

  • for (int i = 1; i <= dataRng.Rows.Count; i++)
    {
    	Int32[] resultTemp = new Int32[j];
    	for (int j = 1; j <= dataRng.Columns.Count; j++)
    	{
            	resultTemp[j - 1] = Convert.ToInt32((dataRng.Cells[i, j] as Excel.Range).Value);
    		if (resultTemp[j - 1] > numNodos)
    			numNodos = resultTemp[j - 1];
    	}
    	allResults.Add(resultTemp);
    } 
    

    Sino la lista contiene en todos los elementos la referencia al mismo objeto, que se va reescribiendo con nuevos valores.

    Cada elemmento de la lista debe ser un objeto diferente.


    [W]

    • Marcado como respuesta alexcumbal viernes, 22 de agosto de 2014 18:26
    jueves, 21 de agosto de 2014 21:10

Todas las respuestas

  • for (int i = 1; i <= dataRng.Rows.Count; i++)
    {
    	Int32[] resultTemp = new Int32[j];
    	for (int j = 1; j <= dataRng.Columns.Count; j++)
    	{
            	resultTemp[j - 1] = Convert.ToInt32((dataRng.Cells[i, j] as Excel.Range).Value);
    		if (resultTemp[j - 1] > numNodos)
    			numNodos = resultTemp[j - 1];
    	}
    	allResults.Add(resultTemp);
    } 
    

    Sino la lista contiene en todos los elementos la referencia al mismo objeto, que se va reescribiendo con nuevos valores.

    Cada elemmento de la lista debe ser un objeto diferente.


    [W]

    • Marcado como respuesta alexcumbal viernes, 22 de agosto de 2014 18:26
    jueves, 21 de agosto de 2014 21:10
  • Pareciera que la lista funcionara sólo como una especie de Pointer (Recordando C).

    No es la lista. Es el resultTemp el que funciona como una especie de Pointer (en realidad es una Referencia en lugar de un Pointer, pero el efecto es el mismo).

    A cada vuelta del bucle, le metes distintos valores al array; esos valores se guardan en la zona de memoria a la que apunta el pointer. Después, guardas el pointer en la lista. El resultado es que todas las entradas de la lista tienen el mismo pointer, y por tanto todas apuntan a la misma zona de memoria y ven los mismos valores (los últimos que se metieron, no los que había cuando copiaste el pointer a la lista).

    El remedio es el que ya te han indicado en el mensaje anterior: haz un "new" del array a cada vuelta del bucle para que se genere un nuevo pointer.

    viernes, 22 de agosto de 2014 8:41
  • Muchas gracias por la respuesta, ya había logrado hacerlo funcionar, declarando el arreglo dentro del método Add(),  pero obviamente era algo completamente impráctico. Esta era la solución que buscaba.

    Saludos


    Alexánder Cumbal

    viernes, 22 de agosto de 2014 18:29
  • Muchas gracias por la aclaración adicional, bastante útil, la verdad no sabía que en C# los array funcionaban también como Pointers.

    Saludos


    Alexánder Cumbal

    viernes, 22 de agosto de 2014 18:31