2013-07-16 36 views
18

Tôi vẫn còn nghi ngờ về object. Nó là lớp cơ sở chính của bất cứ thứ gì, bất kỳ lớp nào. Nhưng nó là kiểu tham chiếu hay kiểu giá trị. Hoặc giống như những hành vi này? Tôi cần phải làm rõ điều này. Tôi gặp khó khăn khi hiểu điều đó.Đối tượng có phải là loại tham chiếu hoặc loại giá trị không?

 object obj1 = "OldString"; 
    object obj2 = obj1; 
    obj1 = "NewString"; 
    MessageBox.Show(obj1 + " " + obj2); 
    //Output is "NewString OldString" 

Trong trường hợp này, nó hoạt động như một loại giá trị. Nếu đối tượng là kiểu tham chiếu thì tại sao giá trị obj2 vẫn là "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" 

Trong trường hợp này nó hoạt động như kiểu tham chiếu

Chúng ta có thể suy luận rằng loại object 's là những gì bạn hộp bên trong nó. Nó có thể là cả kiểu tham chiếu và loại giá trị. Đó là về những gì bạn hộp bên trong. Tôi có đúng không?

Trả lời

22

Nó là một loại tài liệu tham khảo

Làm một ví dụ với chuỗi không phải là rất sáng, bởi vì chuỗi là cũng một loại tài liệu tham khảo (như là SampleClass, rõ ràng); ví dụ của bạn không chứa "quyền anh".

nếu đối tượng là kiểu tham chiếu thì tại sao giá trị obj2 vẫn là "OldString"

Tại sao nó sẽ không được? Khi bạn tạo một chuỗi mới , không thay đổi tham chiếu cũ để trỏ vào chuỗi mới. Xem xét:

 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

sử dụng một chuỗi như một ví dụ là một ý tưởng siêu xấu. chuỗi là tham chiếu nhưng nó cũng không thay đổi. Khi bạn tạo một cái mới, đầu tiên nó sẽ xem qua chuỗi ký tự để xem chuỗi đã tồn tại chưa. chuỗi là một trường hợp siêu đặc biệt, không sử dụng nó để giải thích các khái niệm xung quanh tham chiếu và giá trị typs. – Markus

+0

"Khi bạn tạo một cái mới, đầu tiên nó sẽ xem qua chuỗi ký tự để xem chuỗi đã tồn tại chưa." - đó ... không thực sự đúng. Nó sẽ kiểm tra trong * một số trường hợp *, nhưng không phải trong trường hợp chung. Đối với lý do tại sao tôi sử dụng chuỗi ở nơi đầu tiên: * bởi vì câu hỏi đã được thảo luận cụ thể về chuỗi *. –

9

Khi bạn làm

obj1 = "NewString"; 

nó thực sự nắm giữ một mới tham khảo, đến một vị trí bộ nhớ, không phải là vị trí mà bạn đã cung cấp cho obj2 trước. Khi bạn thay đổi nội dung của vị trí obj1, bạn sẽ nhận được thay đổi tương tự trong obj2.

Hãy thử thay đổi nội dung của obj1 với

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

Cả hai dây của bạn bây giờ sẽ "0ldString".

Điều này là do đối tượng là loại tham chiếu.

+0

nhờ sharpler kinda đã giúp – UfukSURMEN

7

Biến số object luôn là loại tham chiếu.

Có thể cho object để "tham chiếu" một loại giá trị theo sức mạnh của quyền anh. Hộp là một trình bao bọc kiểu tham chiếu xung quanh một giá trị, trong đó biến số object đề cập đến.

int x = 10;  // a value-type 
object o = x; 

Biến o là một tham chiếu đến một ô chứa giá trị của x - nhưng nó không phải x:

x = 20; 
MessageBox.Show(string.Format("x:{0} o:{1}", x, o)); 

Điều này có thể chiếu sáng hơn với một giá trị kiểu có thể thay đổi:

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 là tham chiếu được đóng hộp đến x, vì vậy, hãy thay đổi x 's val ue không có hiệu lực trên o.

Thay đổi SampleClass thành lớp thay vì cấu trúc (loại tham chiếu thay vì loại giá trị) sẽ thay đổi hành vi: dòng object o = x; sẽ làm o tham chiếu cùng điều với x và thay đổi văn bản của x cũng sẽ thay đổi văn bản của o.

+0

cảm ơn lời giải thích – UfukSURMEN

+0

giải thích rất rõ Steve. Vì vậy, trong trường hợp của int, nó là tạo wrapper. Tuy nhiên, trong trường hợp struct, nó được chuyển đổi trực tiếp sang kiểu ref. Tôi có đúng không? Tôi chỉ tự hỏi, tại sao .net framework không tuân theo cùng một kỹ thuật cho cả hai? Tôi có nghĩa là, tại sao không thể int được chuyển đổi trong ref-type hoặc tại sao struct không thể được chỉ định bởi wrapper vào nó? – Akie

0

Biến đối tượng luôn là loại tham chiếu. Lớp và chuỗi là loại tham chiếu. Cấu trúc và enum là loại giá trị. Tôi đã tập hợp một ví dụ lớn từ nhiều nguồn khác nhau.

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

Tài liệu tham khảo - http://jonskeet.uk/csharp/references.html

+0

Cảm ơn bạn đã giải thích. nó thực sự là hướng dẫn – UfukSURMEN

Các vấn đề liên quan