Its only a theoretical question, but I can't get a good answer:
If I pass a parameter by ref
, the object itself is passed and not a copy.
Here is what confuses me: As far as I know, each method has its own stack frame - memory, which they can't leave. So does that mean a ref - Object gets packed on the Heap and there is a reference to this parameter, or does the method go into the stack of the calling method and works there?
I'm sorry if my question is confusing, I basically would like to know how a ref type is saved and what impact it has.
Edith: I think I didnt make myself clear. I understand the concept of value and refence types. To make it easier, I try to explain it just by a value type, lets say Int:
Procedure 1 calls Prodecure 2 by passing an Int ByVal. This int has its own memory on the Stack of Prodecure 2, which means, altering this value in P2 doesnt change the Value in P1, since this 2 values are saved in each Stack once.
Now the same with byref: Prodecure 2 doesnt save a Copy of Int, but has access to this value directly. There are (in my Oppinion) two possibilies to make this work:
Does this make it more clear what I mean?
The parameter that is passed is an address to some object. That reference is passed on the stack, along with all other parameters to the method.
The actual object itself lives wherever it lived before you called the method. That could be in the stack, it could be in the heap, it doesn't matter. The act of passing an object by reference does not result in it being moved in memory, from say the stack to the heap, or from the heap to the stack.
Although Servy has correctly answered the question, it seems there's an awful lot of confusion as to what the difference is between passing a parameter with ref
and passing the reference of the object by value. For that reason, I think it's worth providing a short illustration.
Assume the following simple class:
class Player
{
public Player(int health)
{
Health = health;
}
public int Health { get; set; }
}
We can now test updating the properties of the object and also changing the reference itself:
static void Main(string[] args)
{
Player player = new Player(100);
Console.WriteLine(player.Health);
ChangeHealth(player);
Console.WriteLine(player.Health);
ChangeHealthByRef(ref player);
Console.WriteLine(player.Health);
ChangePlayer(player);
Console.WriteLine(player.Health);
ChangePlayerByRef(ref player);
Console.WriteLine(player.Health);
}
static void ChangeHealth(Player player)
{
player.Health = 80;
}
static void ChangeHealthByRef(ref Player player)
{
player.Health = 60;
}
static void ChangePlayer(Player player)
{
player = new Player(40);
}
static void ChangePlayerByRef(ref Player player)
{
player = new Player(20);
}
Output:
100
80
60
60
20
ChangeHealth
successfully modifies the Health
property of the player
object.
ChangeHealthByRef
also successfully modifies the Health
property of the player
object. So you can see, in both calls, the object to which player
refers, can be modified, in spite of ChangeHealth
using a copy of the reference.
Now, here's the part where I think people are getting confused:
ChangePlayer
creates a new Player
object which modifies the copy of the reference passed in. That means the change does not reflect in the calling code (i.e. Health
still = 60).
ChangePlayerByRef
also creates a new Player
object but, this time, it's modifying the reference directly, which means the change does reflect in the calling code (i.e. Health
= 20).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With