Является ли объект ссылочным типом или типом значений?
У меня все еще есть сомнения относительно object
. Это первичный базовый класс, любой класс. Но это ссылочный тип или тип значения. Или как это происходит? Мне нужно выяснить это. Мне трудно понять это.
object obj1 = "OldString";
object obj2 = obj1;
obj1 = "NewString";
MessageBox.Show(obj1 + " " + obj2);
//Output is "NewString OldString"
В этом случае он действует как тип значения. Если объектом был ссылочный тип, то почему значение obj2 по-прежнему остается "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"
В этом случае он действует как ссылочный тип
Мы можем вывести, что тип object
- это то, что вы помещаете внутри него. Это может быть как ссылочный тип, так и тип значения. Речь идет о том, что вы внутри. Я прав?
Ответы
Ответ 1
Это ссылочный тип
Выполнение примера со строкой не очень освещается, потому что строка также ссылочного типа (как есть SampleClass
, очевидно); ваш пример содержит нулевой "бокс".
Если объект является ссылочным типом, то почему значение obj2 по-прежнему остается "OldString"
Почему бы и нет? Когда вы создаете новую строку, это не изменяет старые ссылки, чтобы указать на новую строку. Рассмотрим:
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"
Ответ 2
Когда вы делаете
obj1 = "NewString";
он фактически содержит новую ссылку, в другую ячейку памяти, а не в том же месте, которое вы ранее указывали obj2
. Когда вы измените содержимое местоположения obj1
, вы получите такое же изменение в obj2
.
Попробуйте изменить содержимое obj1
с помощью
fixed(char* c = obj1 as string)
{
c = '0';
}
Теперь обе ваши строки будут "0ldString"
.
Это потому, что объекты являются ссылочными типами.
Ответ 3
Переменная object
всегда является ссылочным типом.
Можно object
"ссылаться" на тип значения по силе бокса. Поле представляет собой обертку ссылочного типа вокруг значения, к которому относится переменная object
.
int x = 10; // a value-type
object o = x;
Переменная o
является ссылкой на поле, содержащее значение x
- но это не x
:
x = 20;
MessageBox.Show( string.Format( "x:{0} o:{1}", x, o ) );
Это может быть более освещающим с помощью изменяемого типа значения:
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
- это бокс-ссылка на x
, поэтому изменение значения x
не влияет на o
.
Изменение SampleClass
для класса вместо структуры (ссылочный тип вместо типа значения) изменит поведение: строка object o = x;
сделает o ссылкой на то же, что и x, и изменит x text также изменит текст.
Ответ 4
Объектная переменная всегда является ссылочным типом.
Классы и строка являются ссылочными. Структуры и перечисления являются типами значений.
Я собрал большой пример из разных ресурсов.
// 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 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 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);
}
Ссылки - http://jonskeet.uk/csharp/references.html