Click here to Skip to main content
12,954,672 members (62,319 online)
Click here to Skip to main content
Add your own
alternative version


5 bookmarked
Posted 15 Sep 2009

Ref Keyword for Reference Types

, 15 Sep 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
Learn about the implications of using the ref keyword on reference types.

The Ref keyword is well known. It indicates that you are passing a reference, not a value, to a method. That means that if the method modifies the value, the changes will be apparent to the calling method as well.

Where I see a lot of confusion, however, is what happens when dealing with reference types. It is common to say that methods pass objects by reference, but that's not entirely true.

First, a pop quiz. Without actually running the code, what do you think this code snippet will produce?

using System;

namespace ByRef
    internal sealed class MyClass
        public MyClass(int value)
            Value = value;

        public int Value { get; set; }

    internal class Program
        private static void _SwapByValue(MyClass myClass)
            myClass = new MyClass(5);
        private static void _SwapByRef(ref MyClass myClass)
            myClass = new MyClass(5);
        private static void Main(string[] args)
            MyClass testclass = new MyClass(4);
            MyClass testclass2 = new MyClass(4);
            _SwapByRef(ref testclass2);


We'll come back to that in a minute.

When you make a method call, all of the variables you pass are copied to the stack. This is the first place some people get confused. If I have an integer:

int x = 5;

x is on my stack. A copy of the value of x ("5") is made and also placed on the stack. We now have two stack entries: "my x" and "the method's x."

But what about this?

MyClass myClass = new MyClass(5);

The important thing to remember is that myClass is really a reference to the instance. So the first line gives us two allocations in memory: a block of heap that contains the class, and a local stack pointer to the class. So when we call the method, a copy is made just as in the value type example. In this case, it is a copy of the reference. So now I have my class in the heap, my local reference, and a copy of my local reference being passed to the method.

This is why the first case in the above example will print "4". All the method did was to change the reference on the method's stack to point to a new allocation in the heap - the new instance of MyClass. When the method returns, the copy is forgotten. The new instance (5) becomes orphaned, and is eventually garbage collected. The local reference still points to (4).

The second case is more interesting. As we mentioned, the ref keyword forces a reference, not a copy, to be passed. So this:

int x = 5;
MyMethod(ref x);

Skips making the copy. It simply gives the method access to the "5" value on the stack (some people mistakenly believe that the 5 is somehow boxed or unboxed, but that doesn't happen ... it simply isn't copied). If you change it, you change the same stack reference the calling program has, and therefore it will recognize the change.

What about with our object? This is where understanding the ref keyword is, well, key. Remember that when we new the (4) class, we have two important pieces: the class on the heap, and the pointer to the class (reference) on the stack. When we call the method with the ref keyword, it is not allowed to make a copy. Therefore, the method gains access to the same reference on the stack as the calling program. When it makes a new class (5), the stack reference is changed to point to this new instance. Now, the references point to (5) and (4) is orphaned and will be subject to garbage collection. This is why the second example shows "5" — the reference has been updated.

So, as you can see, objects are not "passed by reference" by default. Instead, when an reference type is passed in a parameter list, the reference is passed by value. This allows you to modify the object. If you want to change the reference, then you must ref it!

Jeremy Likness


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Jeremy Likness
Architect iVision
United States United States
Jeremy Likness is a principal consultant and leads the application development practice at iVision, Inc. Jeremy, an experienced entrepreneur and technology executive, has successfully helped ship commercial enterprise software for 20 years. He specializes in catalyzing growth, developing ideas and creating value through delivering software in technical enterprises. His roles as business owner, technology executive and hands-on developer provided unique opportunities to directly impact the bottom line of multiple businesses by helping them grow and increase their organizational capacity while improving operational efficiency. He has worked with several initially small companies like Manhattan Associates and AirWatch before they grew large and experienced their transition from good to great while helping direct vision and strategy to embrace changing technology and markets. Jeremy is capable of quickly adapting to new paradigms and helps technology teams endure change by providing strong leadership, working with team members “in the trenches” and mentoring them in the soft skills that are key for engineers to bridge the gap between business and technology.

You may also be interested in...

Comments and Discussions

GeneralSimilar article Pin
Darchangel21-Sep-09 6:28
memberDarchangel21-Sep-09 6:28 
GeneralSort of... Pin
Martin Kalitis21-Sep-09 4:54
memberMartin Kalitis21-Sep-09 4:54 
GeneralRe: Sort of... Pin
Jeremy Likness21-Sep-09 5:02
memberJeremy Likness21-Sep-09 5:02 
GeneralRe: Sort of... [modified] Pin
Martin Kalitis21-Sep-09 5:09
memberMartin Kalitis21-Sep-09 5:09 
GeneralRe: Sort of... Pin
Jeremy Likness21-Sep-09 5:16
memberJeremy Likness21-Sep-09 5:16 
GeneralRe: Sort of... Pin
Martin Kalitis21-Sep-09 5:56
memberMartin Kalitis21-Sep-09 5:56 
GeneralRe: Sort of... Pin
Jeremy Likness23-Sep-09 0:06
memberJeremy Likness23-Sep-09 0:06 
No ... because you're still confusing "reference type" with passing "by reference." That's the point of the article. It is true if you pass a value type as a reference type, it gets boxed. But when you pass something by reference, you are not creating a reference type. You are creating a reference to whatever that value is.

It's the wording, I think, that is confusing. While it's not 100% correct, let's try it with calling it "pass by pointer."

Then you have ... you can pass value types or reference types either by a copy or by a pointer to their concrete instance.

In the case of value type ... if I call, a copy is placed on the stack. In the case of reference type, if I call, a copy of the pointer is placed on the stack. Either way I get a copy of something, but in the case of the reference type, the copy is a pointer that points to the original class.

In the case of passing by pointer (using the ref keyword), with value type, I get a pointer to the value type where it is (which is on the stack). With reference type, I get a pointer to the pointer to the class. That's a little more confusing but it says whatever I have in my calling method that points to the heap where the reference type is stored, a pointer to that exact pointer is passed to the method. The method can manipulate the class, but it can now also create an entirely new instance of reference type and change that pointer to point to the new instance, which in turn means the calling method gets a new pointer after the call.

Does that help at all? Again, here is the key at Microsoft:[^]

"Do not confuse the concept of passing by reference with the concept of reference types. The two concepts are not related; a method parameter can be modified by ref regardless of whether it is a value type or a reference type. Therefore, there is no boxing of a value type when it is passed by reference."

That last sentence couldn't be any more clear. When you have a value type in a class then it's a bit different. You know that interview question, "Where are value types stored?" Most people automatically say, "The stack" but value types defined as part of a class are actually stored on the heap with the class.

GeneralRe: Sort of... Pin
Martin Kalitis21-Sep-09 5:02
memberMartin Kalitis21-Sep-09 5:02 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170525.1 | Last Updated 16 Sep 2009
Article Copyright 2009 by Jeremy Likness
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid