2013-07-16 103 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的類型是你裏面框什麼。它既可以是引用類型也可以是值類型。這是關於你在裏面的東西。我對嗎?

回答

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

使用字符串作爲一個例子是一個超級壞主意。字符串是引用,但它也是不可變的。當你創建一個新的字符串時,它首先查看字符串池,看看它是否已經存在。字符串是一個超級特例,不要用它來解釋引用和值類型的概念。 – Markus

+0

「當你創建一個新的字符串時,它首先查看字符串池,看看它是否已經存在。」 - 那是......不是真的。它將檢查*一些情況*,但不是在一般情況下。至於爲什麼我首先使用了字符串:*因爲這個問題是專門討論string *的。 –

9

當你

obj1 = "NewString"; 

它實際上持有參考,到另一個存儲位置,而不是你之前給了obj2相同的位置。當您更改位置obj1的內容時,您將在obj2中獲得相同的更改。

嘗試用

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

改變obj1內容兩者的字符串現在將"0ldString"

這是因爲對象是引用類型。

+0

謝謝sharpler有點幫助 – 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的VAL對o沒有影響。

SampleClass更改爲類而不是結構(引用類型而不是值類型)會改變行爲:行object o = x;將使o指向與x相同的事物,並且更改x的文本也會更改o的文字。

+0

感謝您的解釋 – UfukSURMEN

+0

很好地解釋史蒂夫。所以在int的情況下,它正在創建包裝。但是,在struct的情況下,它直接轉換爲ref-type。我對麼?我只是想知道,爲什麼.NET框架不遵循相同的技術?我的意思是,爲什麼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

相關問題