Click here to Skip to main content
14,327,007 members

Story of Pass By Value and Pass By Reference in C#

Rate this:
3.83 (19 votes)
Please Sign up or sign in to vote.
3.83 (19 votes)
12 Nov 2015CPOL
Misconceptions regarding pass by value and pass by reference in C#

Introduction:

It is a common question which is asked by interviewers in interviews that "What is Pass By Value and Pass By Reference" or "What is the difference between Pass By Value and Pass By Reference". Most of the beginner level developers and also many of the intermediate level developers have misconceptions about it and they answer it wrong during interviews.

When I didn't know the real difference, I used to answer it like, when we pass primitive types they are passed by value but when we pass reference type, they are passed by reference which I was not aware that it is wrong.

So, today I decided to write on this topic so that readers reading my blog could be aware of the real difference and they can correct their misconception regarding it.

Pass By Value in Value Types

In .NET Framework, all objects are by default passed by value not passed by reference either it is a <a href="https://msdn.microsoft.com/en-us/library/s1ax56ch.aspx" target="_blank">Value Type</a> (so called Primitive types like int, char, double, etc.) or Reference Type (class, interface, delegate, string, etc.).

I will not go into the details of Value Type and Reference Type definition and concept, you can read about them here.

Consider the following examples:

First, I will show an example using Value Type:

int num1 = 5;
int num2 = num1;
num2 = 10;

Console.WriteLine(num1);

So what will be printed on Console?

If your answer is 5, then you are right, because int is a value type, it is passed by value, which means for the above code num1 has 5 stored in it, when we create <code>num2 and assign it num1 value of num1 is copied to num2 and after that if we change num2 it will not affect num1, of course because we have copied value of num1 to num2, why num1 is to be changed.

The same happens when we pass value types to methods. For example:

We have created a method with sets the value of an int variable to 10.

private void ChangeValue(int i)
{
   i = 10;
}

Now we call it using our previous example:

int num1 = 5;

ChangeValue(num1);
           
Console.WriteLine(num1);

What would be the output on Console now?

Yes, it will still output 5 as I already said that value is copied, so when ChangeValue method is called, num1 variable value is copied to i so changing i does not change num1.

Diagrammatic/Pictorial Representation of Pass By Value in Value Types

Here is a diagrammatic representation of Pass By Value.

Image 1

Pass By Value in Reference Types

I have the following class of User which is a reference type as classes are reference types:

public class User
{
    public int UserID {get;set;}
    public string Name {get;set;}
}

We create an instance and set its properties, then we assign it to another instance and change Name property and then we print Name on Console to check what is printed:

User objUser = new User() 
{ 
     UserID = 1, 
     Name = "Ehsan Sajjad" 
};

User objUser2 = objUser;
objUser2.Name = "Jon Doe";

When we create Instance of class User, an object is created in memory(Heap) and memory is allocated to it and we are storing reference to that memory location in objUser reference memory (mostly Stack) so that we can use it further, otherwise it will get lost in the memory so we need to keep a reference to it for doing different operation in memory.

When we assign objUser to objUser2 reference of object memory location which objUser is holding copied to objUser2 , now we have two separate copies of reference but they are both pointing to the same memory location which means they both are referencing the same memory location, so changing the value of Name property will change the value in the object in memory of which we have reference in objUser and objUser, hence "Jon Doe" will be printed on console and it will be reflected in both references.

Diagrammatic/Pictorial Representation of Pass By Value in Reference Types

Image 2

We can see the same behavior using a method. See the following method to change Name property of User object:

public static void ChangeName(User user)
{
    user.Name = "Jon Doe";
}

We call it to change the object state, it will give the same behavior that we saw in assignment case:

User objUser = new User() { UserID = 1, Name = "Ehsan Sajjad" };

ChangeName(objUser);

Console.WriteLine(objUser.Name);

When we are passing reference objUser of User object to method ChangeName, reference of memory location is copied to the local object user of method, but they are both pointing to the same memory location which means they both are having reference to the same memory location, so changing the value of Name property will change the value in the object in memory of which we have reference in objUser and user, hence "Jon Doe" will be printed on console.

Here is a diagrammatic representation of it:

Image 3

When the ChangeName(objUser) is called, as it is referring to the same memory location, it will modify the Name property of User object to "Jon Doe".

 

Image 4

But think about what would happen if I set the user to null inside ChangeName method like:

public static void ChangeName(User user)
{
    user = null;
}

and now we call it for objUser:

User objUser = new User() 
{ 
     UserID = 1, 
     Name = "Ehsan Sajjad" 
};

ChangeName(objUser);
Console.WriteLine(objUser.Name);

If you are thinking that it will throw Null Reference Exception, then you are wrong, and if you are thinking that it will output Ehsan Sajjad, then you are right and you have understood that reference is passed by value in C# not by reference.

See the pictorial representation to understand better:

Image 5

Pass By Reference

If we want to make objUser null, we will have to pass it to the method via reference which is done in C# using ref Keyword. We will use the above examples again but this time we will pass them by reference and will see what happens so that we can understand the difference between these two.

Pass By Reference in Value Types

We will use the same above example but this time we will be passing by reference. For that, first of all, we have to change the method signatures of method ChangeValue(int i) to ChangeValue(ref int i), we have added ref keyword with the input parameter which means that when calling this method, the argument should be passed by reference to it:

private void ChangeValue(ref int i)
{
   i = 10;
}

Now we will use the same code as above but we have to use ref keyword at calling side for the parameters that method expects to be passed by reference, otherwise you will get compile time error, and your code will not build:

int num1 = 5;

ChangeValue(ref num1);
           
Console.WriteLine(num1);

This will output 10 on the screen, because we are using ref keyword, in the above code when ChangeValue is called the incoming parameter of it has the same memory address of num1 which is passed as argument that's why now modifying the value of i would reflect the change in num1 as well, in pass by reference new memory location is not used for the method parameter so changing the value of it will reflect the variable that is passed from calling side.

Pass By Reference in Reference Types

We will now check the same thing with reference types, and the behaviour would be the same for reference types case as well, first modify the signature of method so that it takes parameter as reference:

public static void ChangeName(ref User user)
{
    user = null;
}

and we will call it simply this way:

User objUser = new User() 
{ 
     UserID = 1, 
     Name = "Ehsan Sajjad" 
};

ChangeName(objUser);
Console.WriteLine(objUser.Name);

Now when we will call it on objUser setting user to null inside ChangeName will also make objUser null because instead of passing the reference by value (in that a new reference memory location is created which points to the same object) it is passed by reference, so in this case new copy of reference is not created but the reference of objUser is passed to method which results in setting the calling side reference to also change the memory location where it is pointing.

License

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

Share

About the Author

Ehsan Sajjad
Software Developer
Pakistan Pakistan
Ehsan Sajjad is a Microsoft Certified Professional, Microsoft Certified C# Specialist and he is also among the top users on StackOverflow from Pakistan with 50k+ reputation at time of writing this and counting.

He is a passionate software developer with around 5 years of professional experience in Microsoft Technologies both web and desktop applications and always open to learn new things and platforms especially in mobile application development and game development.

Some Achievements :

  • 5th Top Contributor from Pakistan on Stackoverflow.com
  • Top User in ASP.NET MVC from Pakistan on Stackoverflow.com
  • 21st June 2017 - Article of the Day - ASP.NET Community (Beginners Guide on AJAX CRUD Operations in Grid using JQuery DataTables in ASP.NET MVC 5)
  • 19th April 2017 - Article of the Day - ASP.NET Community (ASP.NET MVC Async File Uploading using JQuery)
  • March 2017 - Visual C# Technical Guru Silver Medal on Microsoft Tech Net Wiki Article Competition
  • 20 January 2017 - Article of the Day - ASP.NET Community (Async File Uploading in ASP.NET MVC)
  • 22nd September 2016 - Article of the Day - ASP.NET Community (GridView with Server Side Filtering, Sorting and Paging in ASP.NET MVC 5)
  • 22nd August 2016 - Article of the Day - ASP.NET Community (Beginners Guide for Creating GridView in ASP.NET MVC 5)
  • December 2015 - C-SharpCorner Monthly Winner

Comments and Discussions

 
QuestionGood Article Pin
frikrishna7-Feb-18 14:55
memberfrikrishna7-Feb-18 14:55 
Question[My vote of 2] Reasonable ... though too complicated Pin
irneb11-Oct-15 22:41
memberirneb11-Oct-15 22:41 
AnswerWrong type Pin
Afzaal Ahmad Zeeshan9-Oct-15 21:45
mveAfzaal Ahmad Zeeshan9-Oct-15 21:45 
GeneralRe: Wrong type Pin
Ehsan Sajjad9-Oct-15 22:02
mvpEhsan Sajjad9-Oct-15 22:02 
GeneralRe: Wrong type Pin
OriginalGriff9-Oct-15 22:20
protectorOriginalGriff9-Oct-15 22:20 
GeneralRe: Wrong type Pin
Ehsan Sajjad9-Oct-15 22:24
mvpEhsan Sajjad9-Oct-15 22:24 
QuestionRe: Wrong type Pin
Paul Conrad10-Oct-15 5:52
professionalPaul Conrad10-Oct-15 5:52 
QuestionThis is a very poor presentation. Pin
Member 120239889-Oct-15 9:11
memberMember 120239889-Oct-15 9:11 
AnswerRe: This is a very poor presentation. Pin
Ehsan Sajjad9-Oct-15 9:43
mvpEhsan Sajjad9-Oct-15 9:43 
QuestionMy vote of 2 Pin
Member 18804039-Oct-15 1:58
memberMember 18804039-Oct-15 1:58 
AnswerRe: My vote of 2 Pin
Ehsan Sajjad9-Oct-15 2:04
mvpEhsan Sajjad9-Oct-15 2:04 
GeneralRe: My vote of 2 Pin
Member 18804039-Oct-15 2:35
memberMember 18804039-Oct-15 2:35 
GeneralRe: My vote of 2 Pin
Ehsan Sajjad9-Oct-15 3:45
mvpEhsan Sajjad9-Oct-15 3:45 
GeneralRe: My vote of 2 Pin
Member 120239889-Oct-15 9:19
memberMember 120239889-Oct-15 9:19 
GeneralRe: My vote of 2 Pin
Ehsan Sajjad9-Oct-15 10:43
mvpEhsan Sajjad9-Oct-15 10:43 
GeneralRe: My vote of 2 Pin
Member 188040311-Oct-15 22:07
memberMember 188040311-Oct-15 22:07 
GeneralRe: My vote of 2 Pin
Member 1202398813-Oct-15 9:41
memberMember 1202398813-Oct-15 9:41 
GeneralRe: My vote of 2 Pin
Member 188040313-Oct-15 21:44
memberMember 188040313-Oct-15 21:44 

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 7 Oct 2015

Tagged as

Stats

54.4K views
17 bookmarked