Tuesday, October 16, 2018 ..:: Home ::.. Register  Login
All blog entries are the opinions of the author and do not necessarily reflect the opinions of their employer. All the code presented is for explanation and demonstration purposes only. Any damages incurred to your site and/or data are not the responsibility of the author. Every effort is taken to ensure the code properly compiles, however sometimes there are some hiccups and you might be required to do your own debugging.
   TechTidBits (Blog)  

What's the big deal between passing a value around by val or by ref?

May 14

Written by:
Thursday, May 14, 2009 10:14 PM  RssIcon

This week at our study group we had a discussion about passing values around by val and by ref.  How so?  Please read on for further details.

Passing values to a method, sounds easy enough eh?  hhhhmmmmm since when is anything THAT simple?  Ok, coffee in the morning tastes good, ya, that's simple.  haha  But passing a variable into a method can get confusing pretty quickly.

So what's the big deal you ask eh?  Good question!  Well, first off, you have primitives (ex int) vs reference types (string, or some class you create out of thin air).  Primitives are passed around by value on the stack.  Reference types have a pointer/address on the stack pointing to the the actual value on the heap.  Sounds easy enough, but what gets complicated is when you start passing values around to other methods, changing those values and maybe seeing the value change on the way back.

When you pass a primitive to a method, a copy of the value on the stack is pushed onto the stack for the calling method to use.  Did you get that?  Read it over again, A COPY IS PUSHED ONTO THE STACK for the other method to use. Why am I over emphasising this you ask?  Cause when the method is done and it goes out of scope and all it's values get pushed off the stack, including the copied variable value, who's value could have been changed in the method, it's all lost!  So when you return BACK to the calling method, it still has the original value, untouched by anyone else, still as prestine as the millisecond it was copied over.

The source code has an example of calling a method by val and by ref with an int, string and custom object.  Here's a quick picture of what it looks like at runtime.

ByValByRef at runtime

A picture's worth a thousand word's eh?  Thanks for SG for the dual column idea for the illustrations. 

For the int, by val example, notice how the value of i on the stack is copied over to age, still on the stack.  Next, ChangeByVal will change the age value, then when it's done computing, all of ChangeByVal's "things" on the stack are popped off, including the value of age.  Notice how age is it's own separte identity and has nothing to do with i anymore?  That's the key to understanding the "by val" concept.

IntByVal example

Next, we'll cover the by ref example.  The magic here is the CLR recognizes when values are being passed with the ref keyword in the method declaration that it needs to do a bit of additional work as the method finishes, namely copying any address spaces back to the calling method on the stack.

String by val and by ref example

Now, yes, I understand this brief CLR explanation is a gross over simplification and Anders Hejlsberg might be cursing my name, BUT it does help give you a quick and brief explanation of what the difference is between passing values by val and by ref.  By the way, if you still haven't figured it out, by val is the default behaviour for .NET.  You actually have to explicitly demand the by ref changes, and yes, this is more desirable.  This is not to be confused with passing out a reference to a FavouriteNhlTeam and within that object, it points to one team this year, and as they TANK, you switch teams next year, that's a reference within a reference.  And that's ok too.

Now that you know a little bit more about the CLR internal workings, it's time to grab a coffee and get coding!


PS  The astute audience is probably SCREAMING at their LCDs about the out keyword.  The out and ref keywords (from what I can tell and read from Jeffrey Richter, CLR via C#) is they are used interchangeable, EXCEPT for the small change that ref variables be initialized BEFORE being passed out.  Whereas out can be passed around before being initalized, but they'll eventually have to be initialized at some point.  Uh why?  If you're not going to initialize it or use it, then you have to ask why are you passing it around?  LOL


Source Code:


Location: Blogs Parent Separator TechTidBits

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Add Comment   Cancel 
Copyright 1999-2012 by   Terms Of Use  Privacy Statement