0

I assumed that when we pass the reference type to a function, it is pointing to the same object and any changes will be reflected in the main method. But when I initialize the reference to a new object the behavior is not as expected. I understand that it can be done using "ref" keyword but I would to know about this behavior.

class Program
    {
        static void Foo(StringBuilder x)
        {
            x = new StringBuilder(); //if this is not initialized, "helloworld" is printed i.e., same object is getting modified. 
            x.Append("world");
        }

        static void Main(string[] args)
        {
            StringBuilder y = new StringBuilder();
            y.Append("hello");
            Foo(y);

            Console.WriteLine(y.ToString());//I was expecting "world" here.
            Console.ReadLine();
        }
    }
Sunny
  • 4,765
  • 5
  • 37
  • 72
  • You should have expected "hello" ... by reassigning to x, you only reassign a local copy of the reference. – Fildor Aug 25 '17 at 14:54
  • Assigning a new object to a variable is not the same as changing the internals of an object that a variable references. http://jonskeet.uk/csharp/parameters.html – juharr Aug 25 '17 at 14:54
  • Why did you expect it to print "world"? The variable `y` references an object which has only ever had "hello" appended to it. – David Aug 25 '17 at 14:54
  • 2
    I dont understand why it was closed with that question. `String` is immutable, `StringBuilder` not. So even if that is not crucial in this case it is very confusing – Tim Schmelter Aug 25 '17 at 14:57
  • @David, Reason I thought it is "world" because I passed the same reference to the function and it got initialized to a new object with "world" in it. In this case, it is behaving like value type. – Sunny Aug 25 '17 at 14:58
  • 1
    @Sunny: In the function you set the variable `x` to a new object. The variable `y` is unaffected. Two variables point to the same object in memory, then one of them is pointed to a new object in memory. The old object and old variable are unchanged. A *value type* would make a copy. No copy of the object was made. But you explicitly created a new object. That's not a copy, that's an explicit call to `new` that you made. – David Aug 25 '17 at 14:59
  • 1
    You have a reference to the object (instance of StringBuilder), not the variable (x). The 'ref' keyword creates a reference to the variable passed to the function. – fshauge Aug 25 '17 at 14:59
  • 1
    @Sunny It's not a value type, it's a reference type that was passed to the funciton by value. That is any changes to the variable that you passed will not be reflected in the variable passed in (int this case a reference). However if you have done `x.Clear(); x.Append("hello");` that would work. You just cannot assign a new object to a reference like that and expect it to change the passed in variable unless you use the `ref` keyword before the method parameter. – juharr Aug 25 '17 at 15:00
  • @juharr, yes i picked up the same example from the link. As you mentioned, it is initialization that is making a difference. So, in reference types when we initialize it to new object inside a function so it will act as a value type by making its own copy. If it is modified, same object gets modified. Is my understanding right? – Sunny Aug 25 '17 at 15:01
  • 1
    @Sunny: If you would use `x.Clear()` instead of assigning a new reference to the local variable in the method, _then_ you would get your expected result `"world"`. That is because `StringBuilder` is a mutable reference type (as opposed to `string` for example which is also a reference type but immutable). – Tim Schmelter Aug 25 '17 at 15:01
  • 1
    @Sunny: It's not acting as a value type. It's a reference. In the first line of your function you point the reference to a different object in memory. If you don't do that then you can interact with that same object. But once you create a second object, you have a second object. – David Aug 25 '17 at 15:03
  • 2
    @Sunny What you need to understand is that there are reference types which are basically pointers to some memory in the heap and value types which are literally the value. Then you can pass a variable by value or reference. In the case of passing a reference type by value you get a copy of the reference. Assigning to a variable passed by value will only change the local variable. This is true for both reference and value types. – juharr Aug 25 '17 at 15:04
  • Oh now I get it. Thank you all for your inputs! – Sunny Aug 25 '17 at 15:04

0 Answers0