0

So I'm preparing a lesson on pass-by-reference and testing my example... Here I have the following example code:

    public static void Main(string[] args)
    {
        int x = 4;

        Add(x, 4);

        Console.WriteLine("x = {0}", x);

        Player player = new Player("Bob");

        Console.WriteLine("Your name is {0}", player.Name);

        ChangeName(player, "Cobb");

        Console.WriteLine("Your name is {0}", player.Name);
    }

    public static void Add(int x, int y)
    {
        x = x + y;
        Console.WriteLine("(in method) x = {0}", x);
    }

    public static void ChangeName(Player player, string name)
    {
        player.Name = name;
        Console.WriteLine("(in method) Your name is {0}", player.Name);
    }

The first method, Add(x, 5); works as expected, however the ChangeName method alters the player object back in the Main method scope and outputs like this:

(in method) x = 8
x = 4
Your name is Bob
(in method) Your name is Cobb
Your name is Cobb

I'm curious why this is, for years I've been teaching that the Name property of the player instance should not be changed when it comes back to the Main method scope. Have I just been teaching that incorrectly forever? Is the ref keyword only needed for directly passing primitive data types? If that is the case, then what if I explicitly need a shallow copy of the object in the method scope?

Additional Context, in the Player class, the Name property is defined thus:

public class Player
{
    /// <summary>
    /// This player's name.
    /// </summary>
    public string Name
    {
        get;
        set;
    }
...
}
  • 2
    `Player` is a reference type, whilst `int` is a value type – Sean Apr 22 '20 at 14:15
  • 1
    The *reference* to the player object is passed by value. That means that there's a separate reference inside the `ChangeName` method but both references are to the *same* object. It's the object that has a `Name` property. – Damien_The_Unbeliever Apr 22 '20 at 14:19
  • 1
    You are passing a class object which is automatically passed as a reference. Any changes to the class will automatically get changed so when returning from method the changes will be see in the parent code. – jdweng Apr 22 '20 at 14:42
  • Changing `Name` inside method doesn't require `ref`, changing `player` instance will need it (see [this](https://stackoverflow.com/q/961717/1997232)). If you want to protect reference type from being modified you have to clone it before passing (it's automatic for value types, try to use `struct` instead of `class` to see a difference). – Sinatr Apr 22 '20 at 14:48
  • Does this answer your question? [C# pass by value/ref?](https://stackoverflow.com/questions/436986/c-sharp-pass-by-value-ref) – ChiefTwoPencils Apr 22 '20 at 17:07

0 Answers0