Click here to Skip to main content
14,451,614 members

Ref Keyword for Reference Types

Rate this:
4.93 (10 votes)
Please Sign up or sign in to vote.
4.93 (10 votes)
16 Sep 2009CPOL
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
Instructor / Trainer Microsoft
United States United States
Note: articles posted here are independently written and do not represent endorsements nor reflect the views of my employer.

Jeremy Likness is a Cloud Developer Advocate for Azure at Microsoft. Jeremy has spent two decades building enterprise software with a focus on line of business web applications. Jeremy is the author of several highly acclaimed technical books including Designing Silverlight Business Applications and Programming the Windows Runtime by Example. He has given hundreds of technical presentations during his career as a professional developer. In his free time, Jeremy likes to CrossFit, hike, and maintain a 100% plant-based diet.

Jeremy's 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.

Comments and Discussions

GeneralSimilar article Pin
Darchangel21-Sep-09 7:28
MemberDarchangel21-Sep-09 7:28 
GeneralSort of... Pin
Martin Kalitis21-Sep-09 5:54
MemberMartin Kalitis21-Sep-09 5:54 
GeneralRe: Sort of... Pin
Jeremy Likness21-Sep-09 6:02
professionalJeremy Likness21-Sep-09 6:02 
GeneralRe: Sort of... [modified] Pin
Martin Kalitis21-Sep-09 6:09
MemberMartin Kalitis21-Sep-09 6:09 
GeneralRe: Sort of... Pin
Jeremy Likness21-Sep-09 6:16
professionalJeremy Likness21-Sep-09 6:16 
GeneralRe: Sort of... Pin
Martin Kalitis21-Sep-09 6:56
MemberMartin Kalitis21-Sep-09 6:56 
GeneralRe: Sort of... Pin
Jeremy Likness23-Sep-09 1:06
professionalJeremy Likness23-Sep-09 1:06 
GeneralRe: Sort of... Pin
Martin Kalitis21-Sep-09 6:02
MemberMartin Kalitis21-Sep-09 6: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.

Technical Blog
Posted 16 Sep 2009

Tagged as


5 bookmarked