What are the things to consider when choosing between ByRef and ByVal.
I understand the difference between the two but I don't fully understand if ByRef saves resources or if we even need to worry about that in the .Net environment.
How do you decide between the two if the functionality doesn't matter in a situation?
The default is ByVal , but be sure you understand what passing by value and by reference actually means. You almost always want to pass ByVal , and this is in fact the default.
C# Passing arguments by default is ByRef instead of ByVal.
When we pass a value to a procedure we may pass it ByVal or ByRef. The ByVal sends a copy of the argument's value to the procedure. The ByRef sends a reference indicating where the value is stored in memory, allowing called procedure to actually change the argument's original value.
The advantage of passing an argument ByRef is that the procedure can return a value to the calling code through that argument. The advantage of passing an argument ByVal is that it protects a variable from being changed by the procedure.
There's a lot of misinformation around about this. The main thing is that you understand the difference between value types and reference types, and the difference between pass by value and pass by reference.
You almost always want to pass by value. Passing by reference is almost always for "I want to return more than one result, and not just by adding things to a list which is passed in." The classic example of a method using pass-by-reference is Int32.TryParse where the return value is a success/failure, and the parsed value is "returned" by an out parameter.
The default is byValue for ALL types, but it is important to understand what the two options mean for a "reference type" (a class) as opposed to a value type. (structs).
For a reference type, if you declare a reference type variable in a method, that variable is a memory location in the stack frame of the method. It is not on the heap. When you initialize that variable (using new or a factory, whatever), then you have created an actual object on the heap, and the address of that object is stored in the declared reference variable in your methods stack frame.
When you pass a reference type to another method byVal, you are creating a copy of the address stored in the calling methods stack and passing the copy of that value (the pointer address) to the called method, where it is stored in a new memory slot in the called methods stack. Inside the called method, the new cloned variable points directly to the same object on the Heap. So using it can change the properties of the same object. But you cannot change which heap object the original reference variable (on the calling methods stack) points to. If, in the called method I write
myVar = new object();
The original variable in the calling method will not have changed to point to a new object.
If I pass a reference type byRef, otoh, I am passing a pointer to the declared variable in the calling methods stack (which contains a pointer to the object on the heap) It is therefore a pointer to a pointer to the object. It points to the memory location on the calling methods stack, which points to the object on the heap.
So now, if I change the value of the variable in the called method, by setting it to a new object(), as above, since it is a "refereence" to the variable in the calling method, I am actually changing which object the variable in the calling method is pointing to. So After the called method returns, the variable in the calling method will no longer be pointing to the same original object on the heap.
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