-1

In c#, as objects are reference types, why is below output d100? Should it not be d500 as we changed it in ChangeReferenceObj and both o and a are pointing to same object?

using System; 
public class Program {

    static void ChangeReferenceObj(object a) 
    {
        Console.WriteLine("e"+a); 
        a=500; 
        Console.WriteLine("f"+a);
    }

    public static void Main(string[] args)
    {          
        object o=100;
        Console.WriteLine("b"+o);
        ChangeReferenceObj(o);     
        Console.WriteLine("d"+o);
    }
}

Output:

b100
e100
f500
d100

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Tommy1987
  • 9
  • 1
  • 3
    Hint: "Boxing". – Joel Coehoorn Oct 13 '21 at 20:45
  • 4
    In `ChangeReferenceObj`, the parameter `a` refers to the same object as `Main`'s `o`. `ChangeReferenceObj` then changes `a` so it now refers to a new object (500). The `o` in `Main` still refers to the original `100`. To let `ChangeReferenceObj` modify `Main`'s variable, use `ChangeReferenceObj(ref object a)`. – Raymond Chen Oct 13 '21 at 20:45
  • Not all objects in C# are reference types. And even if they were, reassigning a (non-`ref`/`in`/`out`) parameter referring to a reference type does *not* modify the object to which the variable refers - it changes which object it refers to. Look up the difference between value types and reference types, the concept of "boxing", and read [this guide on parameter passing](https://jonskeet.uk/csharp/parameters.html). – Joe Sewell Oct 13 '21 at 20:45
  • 1
    @JoelCoehoorn It is a poor hint. This would happen without boxing as well, say if `o = new List()` and `a = new HashSet()`. – Jeppe Stig Nielsen Oct 13 '21 at 20:56
  • 2
    When you pass parameters you always pass them by ***value*** unless you specify the `ref` keyword. Now, the important thing to note here - ***and this is what I think you're misunderstanding*** - is that the ***value*** of a ***reference type*** is the ***reference*** and when you assign a new value you are changing the ***value*** of the ***passed in parameter*** to a new ***reference***. The original variable, from the calling method, still has the original ***reference***. It's only when you pass a reference-type by ***reference*** that you get the behaviour you're looking for. – Enigmativity Oct 13 '21 at 21:03
  • [Try these examples (C# source encoded in URL).](https://tio.run/##pZMxb4MwEIV3fsVTlhC1IWrGok5MQY0UlaGzgSOyRGywIRWK8tupwWloaT11w7679727M5leZ1JR37eaiyOSTjd0Cj0vK5nWiLyLB1RtWvIMXDTYhd7V041qswbJPBiH2GxwahuWlgSb9YhKas3TssMiZ@JISrZ6YUSMCmtMoQUdRq3b1VnyHHvGhb8yl0MAODMFiRcI@kCEC3bm@wnXcAzuZc6LLhqUfLmyd5EUWpYUvCve0CsX5C/kMxZ4gAx2JueuWt1UE6Ma/1ZNxjb8yi1bWdkqiL/L1i6zb2Rs8qMY7R6YYidqSPm1G1BbQP3Tt3L5/gJY5xNBuQnKEtTYAnD15sv4NuAI2bSWLBh629qiv2pu40ugpyIdxK4ix3AGJobHJSSoKGh4V60mLBUVS/AClUlfp93anME1ctJcUT7ZnC1ja2flos8nN7j/D17PVnXHm/@g7z8B) – Jeppe Stig Nielsen Oct 13 '21 at 21:23
  • 1
    @enigmativity that is the correct answer, so why not post this as the answer rather than a comment? – Nigel Oct 13 '21 at 21:26
  • 1
    Folks, the duplicate isn't a duplicate to this question. Please vote to re-open. – Enigmativity Oct 14 '21 at 00:59

3 Answers3

0
using System; 
public class Program {

    static void ChangeReferenceObj(ref object a) 
    {
        Console.WriteLine("e"+a); 
        a=500; 
        Console.WriteLine("f"+a);
    }

    public static void Main(string[] args)
    {          
        object o=100;
        Console.WriteLine("b"+o);
        ChangeReferenceObj(ref o);     
        Console.WriteLine("d"+o);
    }
}

In c# you have to explicitly pass by reference otherwise the default is passed by value.

Meaning you passed the value of the object into the method not the reference to the object.

"Objects aren't passed at all. By default, the argument is evaluated and its value is passed, by value, as the initial value of the parameter of the method you're calling."

Passing Objects By Reference or Value in C#

By assigning an integer to a variable of type object does not make the assignment a reference assignment.

C# assign by reference

Goes a little more into it.

Daniel Kelsch
  • 393
  • 2
  • 10
  • I don't think this is the OP's issue. I think the OP thinks that by assigning an integer to a variable of type `object` which is a reference type, then assignment of `a = 500` should be a reference assignment. I know that's wrong, even for reference types, but that's what the crux of the question is. – Enigmativity Oct 13 '21 at 20:54
  • My bad I did not think about that. – Daniel Kelsch Oct 13 '21 at 20:56
  • It's simple to add that explanation to your answer. With everything you've already got then it would be a comprehensive answer. – Enigmativity Oct 13 '21 at 20:59
0

Your variable o refers to an object. It's important to understand that o is not an object, it only refers to an object. Any number of other variables could independently refer to the same object.

That's what a is. Inside your method, a is just a copy of o. When you change the value of a, it has no effect on o or any other variable that might happen to have the same value.

As others have mentioned, if you want the method to change the value of o, then you have to pass o with the ref keyword. This changes what a is. Instead of being a reference an object, a becomes a reference to a reference to an object. In other words, a becomes a reference to o itself.

Tech Inquisitor
  • 343
  • 1
  • 7
-1

Type Object might not support default as ref, You may need to pass manually.

using System;
class HelloWorld {
    static void ChangeReferenceObj(ref object a)
    {
        Console.WriteLine("e"+a); 
        a=500; 
        Console.WriteLine("f"+a);
    }

    public static void Main(string[] args)
    
    {
        object o=100;
        
        Console.WriteLine("b"+o);
        
        ChangeReferenceObj(ref o);  
        
        Console.WriteLine("d"+o);
    }
}

Output: b100 e100 f500 d500

  • I don't think this is the OP's issue. I think the OP thinks that by assigning an integer to a variable of type object which is a reference type, then assignment of `a = 500` should be a reference assignment. I know that's wrong, even for reference types, but that's what the crux of the question is. – Enigmativity Oct 13 '21 at 20:58