2013-07-16 4 views
18

У меня есть сомнения относительно 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 «s является то, что вы боксировать внутри него. Это может быть как ссылочный тип, так и тип значения. Речь идет о том, что вы внутри. Я прав?

ответ

22

Это ссылочный тип

Делая пример со строкой не очень освещающей, потому что строка также ссылочного типа (как это 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" 
+0

используя строку в качестве примера супер плохая идея. строка является ссылкой, но также неизменной. Когда вы создаете новый, он сначала просматривает пул строк, чтобы увидеть, существует ли такая строка, как она уже существует. string - это особый случай, не используйте его для объяснения понятий вокруг ссылок и типов значений. – Markus

+0

«Когда вы создаете новый, он сначала просматривает пул строк, чтобы увидеть, существует ли такая строка, как она уже существует». - Это ... не совсем так. Он будет проверять * некоторые случаи *, но не в общем случае. Что касается того, почему я использовал строку в первую очередь: * потому что в этом вопросе конкретно обсуждалась строка *. –

9

Когда вы

obj1 = "NewString"; 

это на самом деле имеет новую ссылку, в другую ячейку памяти, а не в том же месте, которое вы дали obj2 раньше. Когда вы меняете содержимое местоположения obj1, вы получите такое же изменение в obj2.

Попробуйте изменить содержание obj1 с

fixed(char* c = obj1 as string) 
{ 
    c = '0'; 
} 

Обе ваши строки теперь будет "0ldString".

Это потому, что объекты являются ссылочными типами.

+0

спасибо sharpler kinda помог – UfukSURMEN

7

Переменная 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 's val ue не влияет на o.

Изменение SampleClass быть класс, а не на структуру (референс-типа вместо значения типа) изменит поведение: линии object o = x; бы сделать о относятся к тем же вещам, как х, и изменение текста X будет также изменения o.

+0

спасибо за разъяснение – UfukSURMEN

+0

очень хорошо объяснил Стив. Поэтому в случае int он создает оболочку. Однако в случае структуры он напрямую преобразуется в ref-type. Я прав? Мне просто интересно, почему .net framework не соответствует той же методике для обоих? Я имею в виду, почему невозможно преобразовать int в ref-type или почему struct не может быть назначен оболочкой на нем? – Akie

0

Переменная объекта всегда является ссылочным. Классы и строка являются ссылочными. Структуры и перечисления являются типами значений. Я собрал большой пример из разных ресурсов.

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

Рекомендации - http://jonskeet.uk/csharp/references.html

+0

Спасибо за ваше объяснение. это действительно поучительно – UfukSURMEN

Смежные вопросы