C# - Passing a Reference vs. Value
In this guide, we will look at the difference between passing reference types and value types as parameters in C# methods.
Jun 12, 2019 • 4 Minute Read
Introduction
In this guide, we will look at the difference between passing reference types and value types as parameters in C# methods. Without understanding this, it can be easy to change the wrong variable and spend hours trying to figure out what happened.
Reference Types
A reference type variable contains a reference to data stored in memory, also known as the heap. The heap is most often used for data that has a longer life. You can have more than one variable point to the same referenced data. Objects are an example of a reference type.
var a = new Student();
var b = a;
In the above example, both variables a and b will point to the same student object in memory. If we change a, we will also change b. This is because a and b are not storing the data but a reference to the location where the data is stored.
Value Types
A value type variable is immutable data which contains the data, instead of a reference to it. Value types often have short lives. They are typically stored in memory in an area known as the stack. The stack is where data that does not need to exist for long lives. Structs, Int32, DateTime, and Double are examples of value types.
Passing a Reference Type
By default, passing a reference type variable to a method passes a copy of the reference, not the actual data. If you change a value inside the reference type, this will also change the value outside the method as well, since it's pointing at the same reference location in memory. A caveat occurs when you try to assign the variable to a new object inside the method. This will make the variable no longer point at the reference object in memory. Any changes thereafter will not be reflected in the original referenced object. Here's an example:
class ReferenceTypeExample
{
static void Enroll(Student student)
{
student.Enrolled = true; // This changes the student variable that was passed in outside of the method.
student = new Student(); // This does not change the student variable outside of the method but creates a new reference. Since student now points to a new reference, the student variable outside of the method is no longer affected after this line.
student.Enrolled = false; // This changes the local student inside the method.
}
static void Main()
{
var student = new Student
{
Name = "Susan",
Enrolled = false
};
Enroll(student);
// student.Name is still Susan
// student.Enrolled is now true
}
}
public class Student {
public string Name {get;set;}
public bool Enrolled {get;set;}
}
Passing a Value Type
When a value type is passed into a method, the value is considered local to the method. Anything done inside the method will not change the original variable.
class ReferenceTypeExample
{
static void Enroll(bool enrollmentStatus)
{
// This will not change any value outside the method.
enrollmentStatus = true;
}
static void Main()
{
var student = new Student
{
Name = "Susan",
Enrolled = false
};
Enroll(student.Enrolled);
// student.Enrolled still equals false.
}
}
public class Student {
public string Name {get;set;}
public bool Enrolled {get;set;}
}
Summary
Knowing these simple techniques can prevent you from making mistakes that change the value of your data.
To learn more about passing reference types, value types, and other types in C# check out Accelerated C# Fundamentals by Scott Allen. Don't forget to try out the C# Path and see where your skills are at and where you can improve!
About the Author
Matt Ferderer is a software developer who tweets, posts and blogs about web development.