简体   繁体   English

对象是引用类型还是值类型?

[英]Is object a reference type or value type?

I have still doubts about object . 我仍然怀疑object It is the primary base class of anything, any class. 它是任何类的任何类的主要基类。 But is it reference type or value type. 但它是引用类型还是值类型。 Or like which of these acts it? 或者喜欢这些行为中的哪一个呢? I need to get this clarified. 我需要澄清一下。 I have difficulty understanding that. 我很难理解这一点。

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

In this case it acts like a value type. 在这种情况下,它就像一个值类型。 If object was reference type then why obj2 value is still "OldString" 如果object是引用类型,那么为什么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"   

In this case it acts like reference type 在这种情况下,它就像引用类型

We can deduce that object 's type is what you box inside it. 我们可以推断出object的类型就是你在里面装的东西。 It can be both a reference type and value type. 它既可以是引用类型,也可以是值类型。 It is about what you box inside. 这是关于你在里面装的东西。 Am I right? 我对吗?

It is a reference type 它是一种参考类型

Doing an example with string isn't very illuminating, because string is also a reference type (as is SampleClass , obviously); 用string做一个例子并不是很有启发性,因为string 也是一个引用类型(显然是SampleClass ); your example contains zero "boxing". 你的例子包含零“拳击”。

if object is reference type then why obj2 value is still "OldString" 如果对象是引用类型,那么为什么obj2值仍为“OldString”

Why wouldn't it be? 为什么不呢? When you create a new string , that doesn't change old references to point at the new string. 创建新字符串时 ,不会将旧引用更改为指向新字符串。 Consider: 考虑:

 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"

When you do 当你这样做

obj1 = "NewString";

it actually holds a new reference, to another memory location, not the same location you gave to obj2 before. 它实际上拥有一个新的引用,到另一个内存位置,而不是之前给obj2的相同位置。 When you change the content of the location obj1 , you will get the same change in obj2 . 当您更改位置obj1的内容时,您将在obj2获得相同的更改。

Try to change the content of obj1 with 尝试更改obj1的内容

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

Both of your strings will now be "0ldString" . 你的两个字符串现在都是"0ldString"

This is because objects are reference types. 这是因为对象是引用类型。

An object variable is always a reference-type. object变量始终是引用类型。

It's possible for object to "reference" a value-type by the power of boxing. object可以通过拳击的力量“引用”值类型。 The box is a reference-type wrapper around a value, to which the object variable refers. 该框是围绕值的引用类型包装器, object变量引用该值。

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

The variable o is a reference to a box containing the value of x - but it's not x : 变量o是对包含x值的框的引用 - 但它不是x

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

This might be more illuminating with a mutable value-type: 对于可变值类型,这可能更有启发性:

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 is a boxed reference to x , so changing x 's value has no effect on o . ox的盒装引用,因此更改x的值对o没有影响。

Changing SampleClass to be a class instead of a struct (reference-type instead of value-type) would change the behaviour: the line object o = x; SampleClass更改为类而不是结构(引用类型而不是值类型)将改变行为:行object o = x; would make o refer to the same thing as x, and changing x's text would also change o's text. 会使o引用与x相同的东西,而改变x的文本也会改变o的文本。

An object variable is always a reference-type. 对象变量始终是引用类型。 Classes and string are reference type. 类和字符串是引用类型。 Struct and enum are kind of value types. 结构和枚举是一种价值类型。 I have put together a big example from various resources. 我汇集了各种资源的一个很好的例子。

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

References - http://jonskeet.uk/csharp/references.html 参考资料 - http://jonskeet.uk/csharp/references.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM