1

Is C# Object/object a value-type or reference type?

I examined that they can keep references but this references can't be used to change objects.

using System;

class MyClass
{
    public static void Swap(Object obj1, Object obj2)
    {
        Console.WriteLine("After Swapping");
        obj1 = 100;
        obj2 = 200;
    }
}

class MainClass 
{
    static void Main(string[] args) 
    {
        Object obj1 = new Object ();
        obj1 = 10;

        Object obj2 = new Object ();
        obj2 = 20;

        Console.WriteLine(obj1.ToString());
        Console.WriteLine(obj2.ToString());

        MyClass.Swap(obj1, obj2);

        Console.WriteLine(obj1.ToString());
        Console.WriteLine(obj2.ToString());

        Console.ReadLine();
    }
}
1
  • Please post some code that demonstrate you cannot change object references. Commented Oct 11, 2009 at 8:27

6 Answers 6

5

Changes you make in Swap are limited to there - you're only playing with pointers (and boxing), the references outside the function stay the same (you have 4 references). You'll see the difference if you changed the signature of your method:

try Swap(ref Object obj1, ref Object obj2).

Same goes for

Object obj1 = new Object ();
obj1 = 10;

This isn't better than Object obj1 = 10;, by the way

To see object is really a references type, use a class with properties, for example:

class Foo {
   public int Value {get; set;}
}

Change the Value of the object in Swap, and you will see the effects on your main program.

Sign up to request clarification or add additional context in comments.

Comments

5

It's a reference type - if you look at the documentation, you'll see it's declared as a class. All classes are reference types.

And yes, the same is true for System.ValueType and System.Enum - they're both reference types as well, despite the names... value types derive from them though.

EDIT: Your update shows that what you're really confused by is parameter passing. See my articles on parameter passing in C# and reference/value types.

1 Comment

I never knew that System.ValueType was itself a reference type... I always assumed it was a value type. It looks like it was made a reference type so that Equals() and GetHashCode() could be overridden to compare content.
2

Please note that

 Object obj1 = new Object ();
 obj1 = 10;

is the same as:

Object obj1 = 10;

Because the compiler intervenes with 'boxing' to turn the value-type int into a reference type. And inside your Swap method you are boxing again, overwriting the reference parameters.

So Kobi's and Dreamwalker's solution, using ref parameters, will actually work:

 public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'

But it is far from ideal.

A better solution would be a generic method:

 static void Swap<T>(ref T x, ref T y)
 {
    T z = x;  x = y;  y = z;
 }

So the compiler can generate the most appropriate code for reference- and value-types.

Comments

0

as object is mother of all objects it is a reference type

Comments

0

It's because the runtime type of obj1 and obj2 is System.Int32 (check with obj1.GetType().ToString()), that is, a value type. No reference copy is made in your Swap function. Instead it just performs boxing and unboxing operations, which have no effect on the real variables.

1 Comment

That wouldn't work for reference types either, not just for int - doing obj1 = new Foo(); changes the reference locally on the function.
0

Your should write code like this:

using System;

class MyClass
{
    public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref'
    {
        Console.WriteLine("After Swapping");
        obj1 = 100;
        obj2 = 200;
    }
}

class MainClass 
{
    static void Main(string[] args) 
    {
        Object obj1 = new Object ();
        obj1 = 10;

        Object obj2 = new Object ();
        obj2 = 20;

        Console.WriteLine(obj1.ToString());
        Console.WriteLine(obj2.ToString());

        MyClass.Swap(ref obj1, ref obj2); // Use keyword 'ref'

        Console.WriteLine(obj1.ToString());
        Console.WriteLine(obj2.ToString());

        Console.ReadLine();
    }
}

You can read more information about keyword 'ref' in MSDN

Quote from MSDN:

Passing Parameters (C# Programming Guide)

In C#, parameters can be passed either by value or by reference. Passing parameters by reference enables function members, methods, properties, indexers, operators, and constructors to change the value of the parameters and have that change persist. To pass a parameter by reference, use the ref or out keyword. For simplicity, only the ref keyword is used in the examples in this topic. For more information about the difference between ref and out, see ref (C# Reference), out (C# Reference), and Passing Arrays Using ref and out (C# Programming Guide). For example:

// Passing by value
static void Square(int x)
{
    // code...
}
// Passing by reference
static void Square(ref int x)
{
    // code...
}

(c) MSDN - Passing Parameters (C# Programming Guide)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.