C#
reference type
value type
programming concepts
.NET

What is the difference between a reference type and value type in c?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, the key difference between a value type and a reference type is what gets copied and how the data is represented. Value types copy the actual value, while reference types copy a reference to an object, which means two variables can end up referring to the same underlying instance.

Value types copy the value itself

Common value types include int, double, bool, DateTime, and struct.

csharp
1int a = 10;
2int b = a;
3
4b = 20;
5
6Console.WriteLine(a); // 10
7Console.WriteLine(b); // 20

When a is assigned to b, the integer value is copied. Changing b later does not affect a.

The same idea applies to structs:

csharp
1public struct Point
2{
3    public int X { get; set; }
4    public int Y { get; set; }
5}
6
7var p1 = new Point { X = 1, Y = 2 };
8var p2 = p1;
9
10p2.X = 99;
11
12Console.WriteLine(p1.X); // 1
13Console.WriteLine(p2.X); // 99

p2 is a copy of the value, not another name for the same Point.

Reference types copy the reference

Classes, arrays, delegates, and strings are reference types in C#.

csharp
1public class Person
2{
3    public string Name { get; set; } = "";
4}
5
6var p1 = new Person { Name = "Ada" };
7var p2 = p1;
8
9p2.Name = "Lin";
10
11Console.WriteLine(p1.Name); // Lin
12Console.WriteLine(p2.Name); // Lin

Here, p1 and p2 point to the same object. Assigning one to the other copies the reference, not a deep copy of the object.

Nullability is another clue

Reference types can normally be null. Traditional value types cannot, unless you wrap them in Nullable<T> or use the ? shorthand.

csharp
int? count = null;
string? name = null;

That is not the full definition of the type system, but it is one of the easiest behavioral differences to observe.

Do not oversimplify to "stack versus heap"

People often memorize this as "value types live on the stack and reference types live on the heap". That is a rough teaching shortcut, not the actual rule.

What matters most is semantics:

  • value types are copied by value
  • reference types are copied by reference

The runtime is free to store data in different places depending on context. For example, a value type can exist inside a heap object as one of its fields.

Boxing and unboxing

When a value type is treated as an object or an interface it implements, it may be boxed. Boxing wraps the value in a reference-type object.

csharp
int number = 5;
object boxed = number;      // boxing
int unboxed = (int)boxed;   // unboxing

This matters because boxing allocates and can have performance implications if it happens heavily in tight loops.

Strings are reference types with value-like behavior

Strings confuse beginners because they are reference types, but they behave immutably.

csharp
1string s1 = "hello";
2string s2 = s1;
3
4s2 = "world";
5
6Console.WriteLine(s1); // hello
7Console.WriteLine(s2); // world

This does not contradict reference-type semantics. s2 = "world" makes s2 refer to a different string object rather than mutating the original one.

Common Pitfalls

  • Thinking the difference is only about stack versus heap storage.
  • Expecting a copied class instance variable to create a new independent object.
  • Forgetting that structs copy by value, which can surprise you when mutating a copy.
  • Ignoring boxing costs when value types are used as object or interfaces.
  • Assuming all reference types are mutable because classes often are.

Summary

  • Value types copy the actual value.
  • Reference types copy a reference to the same underlying object.
  • Structs are value types, while classes and arrays are reference types.
  • Nullability and boxing behave differently for the two categories.
  • The most useful mental model is copy semantics, not a simplified stack-versus-heap rule.

Course illustration
Course illustration

All Rights Reserved.