C# provides for two main data types—value types and reference types. As per the Microsoft documentation1^{1}, a variable of a value type contains an instance of the type, whereas a variable of a reference type contains a reference to an instance of the type. By default, variable values are copied in three situations: on assignment, when passing an argument to a method, and when returning a method result. In the case of value type variables, the corresponding type instances are copied.

Equality comparisons are the fundamental operation that NUnit assertions use and therefore differentiating between the two types is important because it determines how equality comparisons are done.

Listing value and reference types

The list of value and reference types is shown below.

Value types

A data type is a value type if it holds a data value within its own memory space. It means the variables of these data types directly contain values.

  • Structure types
    • User-defined structs, e.g:
       public struct MyCustomStruct
          public int X;
          public int Y;
    • Built-in structure types (simple types)
      • Integral numeric types
        • sbyte
        • byte
        • short
        • ushort
        • int
        • uint
        • long
        • ulong
        • nint
        • uint
      • Floating-point numeric types
        • float
        • double
        • decimal
      • bool
      • char
  • Enumeration types

Reference types

Unlike value types, a reference type doesn’t store its value directly. Instead, it stores the address where the value is being stored. In other words, a reference type contains a pointer to another memory location that holds the data.

  • Object (and all classes)
  • String
  • dynamic

Different behavior of value and reference types

Distinguishing between value types and reference types is important because the two behave differently, depending on the situation—assignment statement, passing to a method, or returning from a method. An example of each is provided below.


The following code examples demonstrate the difference between value and reference types. The code in the two is the same, except that in the first example, the assignment is done on a value type, and in the second example, assignment is done on a reference type. In the first example, look at how the value of p1 doesn’t change after p2 is changed.

Get hands-on with 1200+ tech skills courses.