Pregunta

Tengo una variante en la pregunta por ref. Sé todo sobre llamar con la referencia o nuestros parámetros y cómo afecta a las variables y sus valores. Tuve este problema con una DataTable y quiero saber por qué una tabla de datos es diferente a una variable entera simple.

Tengo la respuesta física sobre cómo solucionar el problema, pero quiero saber por qué funciona de la manera que lo hace.

Si usa variables simples, hace lo que esperaba

        int mVar1 = 1;
        int mVar2 =1;

        mVar2 = mVar1;

        mVar2 = 5;

        Console.WriteLine(mVar1.ToString());
        Console.WriteLine(mVar2.ToString());

muestra 1,5 en la consola.

PERO si hace lo mismo con un DataTable, hace referencia a la primera tabla de datos en lugar de un nuevo valor:

        DataTable mVar3 = new DataTable();
        DataTable mVar4 = new DataTable();


         // Create DataColumn objects of data types.
        DataColumn colString = new DataColumn("StringCol");
        colString.DataType = System.Type.GetType("System.String");
        mVar3.Columns.Add(colString);

        // Create DataColumn objects of data types.
        DataColumn colString2 = new DataColumn("StringCol123");
        colString2.DataType = System.Type.GetType("System.String");
        mVar4.Columns.Add(colString2);

        foreach (DataColumn tCol in mVar3.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }
        foreach (DataColumn tCol in mVar4.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }

                mVar4 = mVar3;

        //change mVar4 somehow and see if mVar3 changes


        foreach (DataColumn tCol in mVar4.Columns)
        {
            tCol.ColumnName = "Test";

        }

        foreach (DataColumn tCol in mVar3.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }

        foreach (DataColumn tCol in mVar4.Columns)
        {
            Console.WriteLine(tCol.ColumnName);

        }

La consola muestra: StringCol StringCol123 Prueba Prueba

al decir mVar4 = mVar3 hace que mVar4 sea una referencia a mVar3.

La solución a este problema es decir

DataTable mVar4 = mVar3.Copy(); 

Entonces mi pregunta es: ¿Qué hace que una tabla de datos funcione de manera diferente que un campo entero simple? ¿Por qué crea una referencia cuando uso mVar4 = mVar3 en lugar de una copia diferente de DataTable?

¿Fue útil?

Solución

Se encuentra con la diferencia entre un tipo de referencia y un tipo de valor.

Aquí hay un artículo msdn sobre diferencias .

Una respuesta más descriptiva sería que ambos están realmente realizando la misma operación, la diferencia es que en el primer ejemplo (los dos enteros) la asignación de mVar2 = mVar1 está asignando el valor de mVar1 a mVar2, que es 1. Sin embargo, en el caso de DataTable, lo que realmente se asigna es una ubicación de memoria, no una DataTable.

Digamos, por ejemplo, que la DataTable que creó reside en la ubicación de memoria 20. Eso significaría que la referencia mVar1 mantendría una referencia a esa ubicación (20). Cuando realiza la asignación mVar2 = mVar1, le está diciendo a mVar2 que mantenga el mismo valor que mVar1, por lo que mVar2 también hace referencia a la ubicación de memoria 20. El resultado es que ambas variables hacen referencia a la misma DataTable.

Para lograr el comportamiento que estás describiendo, de hecho necesitarías tener una habilidad Copiar, como has dicho. Tendría que asignar un objeto completamente nuevo y copiar el estado del objeto anterior al nuevo.

Para la clase DataTable, puede ampliarla de esta manera dentro de un método de extensión:

public static DataTable Copy(this DatTable original)
{
   var result = new DataTable();
   //assume Property1 was a property of a DataTable
   result.Property1 = original.Property1; 
   //continue copying state from original to result
   return result;
}

Otros consejos

La llamada mVar2 = mVar1; copia el valor almacenado en la ubicación de mVar1. En este escenario, eso significa que 1 se copia en la ubicación mVar2. En la segunda situación, el valor almacenado en mVar3 se copia nuevamente en la ubicación de mVar4. Sin embargo, en este caso, debido a que DataTable es un tipo de referencia, el valor que se copia es la referencia al objeto DataTable real.

Para mostrar esto aún más, agregue lo siguiente al final del código que publicó:

        mVar4 = new DataTable();
        // Create DataColumn objects of data types.
        DataColumn colString3 = new DataColumn("StringCol1234");
        colString2.DataType = System.Type.GetType("System.String");
        mVar4.Columns.Add(colString3);

        foreach (DataColumn tCol in mVar3.Columns)
        {
            Console.WriteLine(tCol.ColumnName); // still outputs test

        }

        foreach (DataColumn tCol in mVar4.Columns)
        {
            Console.WriteLine(tCol.ColumnName); // now outputs StringCol1234

        }

Aquí, si configura mVar4 en una nueva instancia de DataTable nuevamente, los cambios realizados no se reflejan en mVar3. Esto se debe a que la llamada mVar4 = new DataTable (); cambia la referencia en la ubicación de mVar4, no cambia el objeto al que hace referencia mVar4.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top