Вопрос

I have still doubts about 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"

   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. 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); your example contains zero "boxing".

if object is reference type then why obj2 value is still "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. When you change the content of the location obj1, you will get the same change in obj2.

Try to change the content of obj1 with

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

Both of your strings will now be "0ldString".

This is because objects are reference types.

An object variable is always a reference-type.

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 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:

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.

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; would make o refer to the same thing as x, and changing x's text would also change o's text.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top