c# - tipos - ¿Es el objeto un tipo de referencia o tipo de valor?
tipos de datos variables (4)
Todavía tengo dudas sobre el object
. Es la clase base primaria de cualquier cosa, cualquier clase. Pero es el tipo de referencia o tipo de valor. ¿O como cuál de estos lo actúa? Necesito aclarar esto. Me cuesta entender eso.
object obj1 = "OldString";
object obj2 = obj1;
obj1 = "NewString";
MessageBox.Show(obj1 + " " + obj2);
//Output is "NewString OldString"
En este caso actúa como un tipo de valor. Si el objeto era un tipo de referencia, entonces el valor obj2 sigue siendo "OldString"
class SampleClass
{
public string Text { get; set; }
}
SampleClass Sample1 = new SampleClass();
Sample1.Text="OldText";
object refer1 = Sample1;
object refer2 = refer1;
Sample1.Text = "NewText";
MessageBox.Show((refer1 as SampleClass).Text + (refer2 as SampleClass).Text);
//OutPut is "NewText NewText"
En este caso actúa como tipo de referencia.
Podemos deducir que el tipo de object
es lo que encajas dentro de él. Puede ser tanto un tipo de referencia como un tipo de valor. Se trata de lo que encajas dentro. Estoy en lo cierto
Cuando tu lo hagas
obj1 = "NewString";
en realidad contiene una nueva referencia, a otra ubicación de memoria, no a la misma ubicación que le obj2
a obj2
antes. Cuando cambia el contenido de la ubicación obj1
, obtendrá el mismo cambio en obj2
.
Intenta cambiar el contenido de obj1
con
fixed(char* c = obj1 as string)
{
c = ''0'';
}
Ambas cadenas serán ahora "0ldString"
.
Esto se debe a que los objetos son tipos de referencia.
Es un tipo de referencia
Hacer un ejemplo con una cadena no es muy esclarecedor, porque la cadena también es un tipo de referencia (como es SampleClass
, obviamente); tu ejemplo contiene cero "boxeo".
si el objeto es un tipo de referencia, entonces el valor obj2 sigue siendo "OldString"
¿Por qué no sería? Cuando creas una nueva cadena , eso no cambia las referencias antiguas para que apunten a la nueva cadena. Considerar:
object obj1 = "OldString";
// create a new string; assign obj1 the reference to that new string "OldString"
object obj2 = obj1;
// copy the reference from obj1 and assign into obj2; obj2 now refers to
// the same string instance
obj1 = "NewString";
// create a new string and assign that new reference to obj1; note we haven''t
// changed obj2 - that still points to the original string, "OldString"
Una variable de object
es siempre un tipo de referencia.
Es posible que el object
"haga referencia" a un tipo de valor por el poder del boxeo. El cuadro es una envoltura de tipo de referencia en torno a un valor al que se refiere la variable de object
.
int x = 10; // a value-type
object o = x;
La variable o
es una referencia a un cuadro que contiene el valor de x
, pero no es x
:
x = 20;
MessageBox.Show( string.Format( "x:{0} o:{1}", x, o ) );
Esto podría ser más iluminador con un tipo de valor mutable:
struct SampleClass
{
public string Text { get; set };
public override string ToString() { return Text; }
}
var x = new SampleClass{ Text = "Hello" };
object o = x;
x.Text = "World";
MessageBox.Show( string.Format( "{0} {1}", x, o ) );
o
es una referencia en un recuadro a x
, por lo que cambiar el valor de x
no tiene efecto en o
.
Cambiar SampleClass
para que sea una clase en lugar de una estructura (tipo de referencia en lugar de tipo de valor) cambiaría el comportamiento: la línea object o = x;
haría que o se refiera a lo mismo que x, y cambiar el texto de x también cambiaría el texto de o.
Una variable de objeto es siempre un tipo de referencia. Las clases y la cadena son tipo de referencia. Struct y enum son tipos de valores. He reunido un gran ejemplo de varios recursos.
// PrintedPage is a value type
//this is a struct
struct PrintedPage
{
public string Text;
}
// WebPage is a reference type
class WebPage
{
public string Text;
}
struct SampleClass
{
public string Text { get; set; }
public override string ToString() { return Text; }
}
void Main()
{
// First look at value type behaviour
PrintedPage originalPrintedPage = new PrintedPage();
originalPrintedPage.Text = "Original printed text";
// Copy all the information
PrintedPage copyOfPrintedPage = originalPrintedPage;
// Change the new copy
copyOfPrintedPage.Text = "Changed printed text";
// Write out the contents of the original page.
// Output=Original printed text
Console.WriteLine ("originalPrintedPage={0}",
originalPrintedPage.Text);
//-------------------------------------------------------------------
// Now look at reference type behaviour
WebPage originalWebPage = new WebPage();
originalWebPage.Text = "Original web text";
// Copy just the URL
WebPage copyOfWebPage = originalWebPage;
// Change the page via the new copy of the URL
copyOfWebPage.Text = "Changed web text";
// Write out the contents of the page
// Output=Changed web text
Console.WriteLine ("originalWebPage={0}",
originalWebPage.Text);
// Now change the copied URL variable to look at
// a different web page completely
copyOfWebPage = new WebPage();
copyOfWebPage.Text = "Changed web page again";
Console.WriteLine ("originalWebPage={0}",
originalWebPage.Text);
Console.WriteLine ("copyOfWebPage={0}",
copyOfWebPage.Text);
//-------------------------------------------------------------------
//string are reference type too
object obj1 = "OriginalString"; // create a new string; assign obj1 the reference to that new string "OriginalString"
object obj2 = obj1;// copy the reference from obj1 and assign into obj2; obj2 now refers to // the same string instance
obj1 = "NotOriginalString";// create a new string and assign that new reference to obj1; note we haven''t // changed obj2 - that still points to the original string, "OriginalString"
/* When you do obj1 = "NewString"; it actually holds a new reference, to another memory location, not the same location you gave to obj2 before.
IMP - When you change the content of the location obj1, you will get the same change in obj2.
*/
Console.WriteLine(obj1 + " " + obj2);
//-------------------------------------------------------------------
object onj11 = 2;
object obj12 = onj11;
onj11 = 3; //you assigned boj11 to a new reference but obj12 reference did not change
Console.WriteLine(onj11 + " " + obj12);
//-------------------------------------------------------------------
/*look below - it''s possible for object to "reference" a value-type by the power of boxing. The box is a reference-type wrapper around a value, to which the object variable refers.*/
int i = 2; //int is value type
object j = i; //variable j is a reference to a box containing the value of i- but it''s not i
i = 3;
Console.WriteLine(i + " " + j);
//-------------------------------------------------------------------
var x = new SampleClass{ Text = "Hello" };
object o = x;
x.Text = "World";
Console.WriteLine(x.Text + " " + o);
//-------------------------------------------------------------------
SampleClass x1 = new SampleClass{ Text = "Hello" }; //sample class is of type struct which is value type; it is was of type class then the data would be copied over and result would be World World
SampleClass o1 = x1;
o1.Text = "World";
Console.WriteLine(x + " " + o);
}
Referencias - http://jonskeet.uk/csharp/references.html