Reputation: 29720
Im reading some C# documentation about WCF and IDispatchMessageInspector and the interface defines a 'Message' object that is passed by reference so that it can be manipulated.
What actually happens on the stack when you pass something by ref as opposed to passing normally?
Upvotes: 2
Views: 402
Reputation: 93571
By reference means you can change the original variable passed to the item. It basically passes the address of the variable on the stack rather than the variable value.
As you actually asked what actually happens on the stack here is an IL dump of a by ref and by value method:
.method private hidebysig instance void ByRef(string& s) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldstr "New value"
IL_0007: stind.ref
IL_0008: ret
} // end of method Class1::ByRef
vs.
.method private hidebysig instance void ByValue(string s) cil managed
{
// Code size 9 (0x9)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "New value"
IL_0006: starg.s s
IL_0008: ret
} // end of method Class1::ByValue
As you can see the main difference is the parameter type (string&
instead of string
) and that it does extra steps to load and store the values indirectly.
The simple C# source is shown below for reference:
void ByRef(ref string s)
{
s = "New value";
}
void ByValue(string s)
{
s = "New value";
}
Upvotes: 5
Reputation: 35136
When you pass something by value; a copy of the value type is made and put on stack before the function is called. When you pass something by reference then the address of that is pushed on stack instead of creating a copy and when you modify the object in the function then the original object is being modified instead of the copy.
The way it works is that compiler translates your references to variable to indirect memory access when it sees that the argument was passed by ref.
For example let us assume at memory location 100 you have an integer 123; now when you call a function which accepts in by value (which is default) then copy of 123 will be made and pushed on stack before the function is called which means the copy will now be at (lets say) 160 address. However when you pass something by reference then address 100 will be pushed on stack and will reside on location 160.
Now the instructions generated will read 160 to get the location of object and then modify the data at 100. Indirection will happen same as it is done for pointers when you use * operator.
Upvotes: 0
Reputation: 1500835
It's not the object that's passed by reference - it's the variable.
Basically it aliases the variable used as the argument from the calling side, and the parameter in the method that you call:
public void Foo()
{
int x = 10;
Bar(ref x);
Console.WriteLine(x); // Prints 20
}
public void Bar(ref int y)
{
y = 20;
}
Here, x
and y
are essentially the same variable - they refer to the same storage location. Changes made to x
are visible via y
and vice versa. (Note that in this case it's a local variable in the caller, but it doesn't have to be - if you'd passed an instance variable by reference, then Bar
might call another method which changes the same variable, and then y
would be seen to "magically" change...)
For more about parameter passing in C#, refer to my article on the subject.
Upvotes: 5
Reputation: 5545
by ref means you can create new instance to the object passed, by value cant do that just change the object properties
Upvotes: -1