Click here to Skip to main content
11,502,201 members (61,764 online)
Click here to Skip to main content

C# reference types are passed by value!

, 19 Aug 2010 CPOL 40.5K 11
Rate this:
Please Sign up or sign in to vote.
C# reference types are passed by value!

How many times have I read: "In C# reference types are passed by reference, primitive types by value"? The essential point is that reference types have nothing to do with passing by reference!

But let us start with some basics. There are two types of objects, the value types (structs) where the variable is the object and the reference types which only points to the object. When you pass in a variable to a method, its value gets copied to the method by default. For value types, that means the object itself gets copied. For reference types, that means only the thing that points at the object gets copied!

It is a little bit confusing, because only the reference to the object is copied, not the entire structure. It is a way to save performance, otherwise larger the reference type would be, more performance it would cost. This strategy is also known as call by sharing (which makes it a less confusing than calling it also call by value with reference types). So in a call by value scenario, if the data of a reference type is changed inside the method, the caller variable is also affected. If you change the value of a value type, which is passed to a method, it will not affect the caller variable.

public void Sample()
{
    Point point = new Point(20, 30);
    Person person = new Person() { Name = "Meier" };

    CallByValue(point, person); 

    Console.WriteLine("Point X: {0}", point.X);
    Console.WriteLine("Name: {0}", person.Name); 
}

public void CallByValue(Point point, Person person)
{
    point.X = 10;
    person.Name = "Müller"; 
}

The ref keyword indicates in C# a call by reference. When passing a value type by reference to a method, the changes to the value which are done in the method scope will also affect the variable in the code of the caller. But what happens if you pass reference type to a method by ref?

public void Sample()
{
    Point point = new Point(20, 30);
    Person person = new Person() { Name = "Meier" };

    CallByValue(ref point, ref person); 

    Console.WriteLine("Point X: {0}", point.X);
    Console.WriteLine("Name: {0}", person.Name); 
}

public void CallByValue(ref Point point, ref Person person)
{
    point.X = 10;
    person = new Person() { Name = "Müller" };
}

It allows to change the instance which the variable points to. So you can assign a new object to the variable and also the caller variable will point to the new object. By the way, the behaviour in VB.NET is similar to the behaviour of C#. The only difference is that in VB.NET, you always have to define if you want to pass a value by value or reference.

License

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

Share

About the Author

Mattia Baldinger
Software Developer
Switzerland Switzerland
No Biography provided
Follow on   Twitter

Comments and Discussions

 
GeneralMy vote of 1 Pin
grmrppr10-Sep-12 11:12
membergrmrppr10-Sep-12 11:12 
GeneralMy vote of 2 Pin
gbb2115-Feb-11 17:46
membergbb2115-Feb-11 17:46 
Question[My vote of 2] maybe... handle? Pin
Daniele Rota Nodari24-Aug-10 3:31
memberDaniele Rota Nodari24-Aug-10 3:31 
GeneralPoint Isn't the Object Pin
tf_ics24-Aug-10 3:20
membertf_ics24-Aug-10 3:20 
GeneralMy vote of 1 Pin
aganyadevi23-Aug-10 23:48
memberaganyadevi23-Aug-10 23:48 
GeneralNot sure I agree either Pin
Richard MacCutchan23-Aug-10 10:47
mvpRichard MacCutchan23-Aug-10 10:47 
GeneralI don't think you're right Pin
Michal Blazejczyk23-Aug-10 10:37
memberMichal Blazejczyk23-Aug-10 10:37 
GeneralExactly Pin
supercat920-Aug-10 6:14
membersupercat920-Aug-10 6:14 
GeneralRe: Exactly Pin
Silic0re0920-Aug-10 7:55
memberSilic0re0920-Aug-10 7:55 
GeneralConfusing title... [modified] Pin
Silic0re0920-Aug-10 3:53
memberSilic0re0920-Aug-10 3:53 
Just wanting to clear it up, as the way it was presented is a bit confusing...

In C++, the equivalent prototype for your first example would be:

void CallByValue(Point point, const Person *person);

And the call from your Sample function pretty much evaluates to:

CallByValue(point, &person);

As you can see, the address of (reference to) the Reference Type Person is passed to the function where the actual value can be changed.

Here is an excerpt from the help:

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.


Here is the excerpt from the programming guide:


A variable of a reference type does not contain its data directly; it contains a reference to its data. When you pass a reference-type parameter by value, it is possible to change the data pointed to by the reference, such as the value of a class member. However, you cannot change the value of the reference itself; that is, you cannot use the same reference to allocate memory for a new class and have it persist outside the block. To do that, pass the parameter using the ref or out keyword.


The key concept to remember here is that reference types are passed as references to the object. The difference comes in that reference types passed without the ref keyword can only have the internal data changed, but not the reference itself. If you pass a reference type with the ref keyword, not only can you change the data that the reference type contains, but you can point that reference at a different or new object.

modified on Friday, August 20, 2010 9:59 AM

GeneralRe: Confusing title... Pin
Ninja-the-Nerd23-Aug-10 16:11
memberNinja-the-Nerd23-Aug-10 16:11 
GeneralRe: Confusing title... Pin
johannesnestler26-Aug-10 2:33
memberjohannesnestler26-Aug-10 2:33 
GeneralRe: Confusing title... Pin
Ninja-the-Nerd26-Aug-10 8:03
memberNinja-the-Nerd26-Aug-10 8:03 
Generalhave 5 Pin
Pranay Rana20-Aug-10 1:23
memberPranay Rana20-Aug-10 1:23 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150520.1 | Last Updated 20 Aug 2010
Article Copyright 2010 by Mattia Baldinger
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid