Back to all articles

DotNet

Variables and Data Types in C#: Value Types, Reference Types, and var Explained

Learn how variables and data types work in C#, including var, value types, reference types, arrays, strings, and the difference between copying values and references.

8 min read

0 comments

When you start learning C#, one of the first concepts you encounter is variables and data types.

They may look simple at first, but understanding how variables store values—and especially the difference between value types and reference types—will save you from many confusing bugs later.

In this article, we'll understand:

  • What variables are
  • Common C# data types
  • What var actually means
  • Value types
  • Reference types
  • Why arrays behave differently from integers
  • Why string is a special reference type
  • The difference between changing an object and reassigning a variable

---

1. What Is a Variable?

A variable is a named location used to store a value in your program.

For example:

int age = 25;
string name = "Amit";
bool isActive = true;
decimal salary = 35000.50m;

Each variable has a type.

The type tells C#:

  • What kind of value can be stored
  • How much memory may be needed
  • Which operations are allowed on the value

Consider:

int age = 25;

Let's break it down:

int age = 25;
│   │    │  │
│   │    │  └── Value
│   │    └───── Assignment operator
│   └────────── Variable name
└────────────── Data type

Here:

  • int is the data type.
  • age is the variable name.
  • = assigns a value to the variable.
  • 25 is the value.
  • ; ends the C# statement.

---

2. Common Data Types in C#

C# provides many built-in data types.

Some of the most commonly used ones are:

TypeUsed ForExample
intWhole numbersint count = 10;
doubleFloating-point calculationsdouble temperature = 36.6;
decimalHigh-precision decimal calculations, commonly moneydecimal price = 99.50m;
boolTrue or false valuesbool isApproved = false;
charA single characterchar grade = 'A';
stringTextstring city = "Pune";

Why does decimal use m?

You may notice this:

decimal price = 99.50m;

The m suffix tells the compiler that 99.50 should be treated as a decimal literal.

Without the suffix:

decimal price = 99.50;

the compiler treats 99.50 as a double, which cannot be implicitly assigned to a decimal.

So we write:

decimal price = 99.50m;

---

3. What Does var Mean?

C# also allows you to declare local variables using var.

For example:

var age = 25;
var name = "Amit";

Some beginners think that var means the variable can store anything.

It does not.

The compiler looks at the initial value and determines the actual type.

For example:

var age = 25;

The compiler sees 25 and determines that age is an int.

Similarly:

var name = "Amit";

The compiler determines that name is a string.

Therefore, these two declarations are effectively equivalent:

int age = 25;

and

var age = 25;

Once the type has been inferred, it remains fixed.

This will not work:

var age = 25;

age = "Twenty-five";

The compiler reports an error because age was inferred as an int.

Remember

var means "let the compiler infer the type." It does not mean "any type."

C# is still a statically typed language.

---

4. Value Types

One of the most important concepts in C# is understanding value types.

Consider this example:

int first = 10;
int second = first;

second = 20;

Console.WriteLine(first);
Console.WriteLine(second);

Output:

10
20

Why didn't changing second affect first?

Because int is a value type.

When we write:

int second = first;

the value stored in first is copied into second.

Conceptually:

first
┌────┐
│ 10 │
└────┘

second
┌────┐
│ 10 │
└────┘

They are now separate variables containing separate values.

When we execute:

second = 20;

we get:

first
┌────┐
│ 10 │
└────┘

second
┌────┐
│ 20 │
└────┘

Changing second does not affect first.

Common value types include:

int
long
double
float
decimal
bool
char
struct
enum

---

5. Reference Types

Reference types behave differently.

Consider an array:

int[] first = { 10, 20 };
int[] second = first;

second[0] = 99;

Console.WriteLine(first[0]);
Console.WriteLine(second[0]);

Output:

99
99

This surprises many beginners.

Why did changing second also appear to change first?

Because arrays are reference types.

When we write:

int[] second = first;

C# does not create another array automatically.

Instead, the reference stored in first is copied into second.

Both variables therefore refer to the same array object.

Conceptually:

first ──────┐
            │
            ▼
        ┌─────────┐
        │ 10 | 20 │
        └─────────┘
            ▲
            │
second ─────┘

Now execute:

second[0] = 99;

The array becomes:

first ──────┐
            │
            ▼
        ┌─────────┐
        │ 99 | 20 │
        └─────────┘
            ▲
            │
second ─────┘

There is only one array.

Both variables refer to it.

That is why:

Console.WriteLine(first[0]);

prints:

99

---

6. An Array of Integers Is Still a Reference Type

This is another common confusion.

You might think:

"int is a value type, so shouldn't int[] also be a value type?"

No.

The elements inside the array are integers, but the array itself is an object.

Therefore:

int number = 10;

Here, number is a value type.

But:

int[] numbers = { 10, 20, 30 };

Here, numbers refers to an array object, so the array is a reference type.

The type of the elements and the type of the container are separate concepts.

---

7. Modifying an Object vs Reassigning a Variable

This distinction is extremely important.

Look at this example:

int[] first = { 10, 20 };
int[] second = first;

Initially:

first ───┐
         ▼
      [10, 20]
         ▲
second ──┘

Both refer to the same array.

If we do:

second[0] = 99;

we are modifying the shared array.

Therefore both variables see:

[99, 20]

But consider this instead:

second = new int[] { 99, 100 };

We are not modifying the original array.

We are changing what second refers to.

Conceptually:

first ─────► [10, 20]

second ────► [99, 100]

Now:

Console.WriteLine(first[0]);
Console.WriteLine(second[0]);

Output:

10
99

The important difference is:

second[0] = 99;

means:

Modify the object that second refers to.

While:

second = new int[] { 99, 100 };

means:

Make second refer to another object.

Understanding this difference makes reference types much easier to reason about.

---

8. What About string?

string creates an interesting situation.

Strings are reference types, but they behave differently from mutable objects such as arrays.

Consider:

string first = "Hello";
string second = first;

second = "Hi";

Console.WriteLine(first);
Console.WriteLine(second);

Output:

Hello
Hi

You may wonder:

If strings are reference types, why didn't first also become "Hi"?

Because strings are immutable.

Immutable means:

Once a string object has been created, its contents cannot be changed.

Initially:

first ──┐
        ▼
     "Hello"
        ▲
second ─┘

Then:

second = "Hi";

does not modify "Hello".

Instead, second is made to refer to another string.

Conceptually:

first  ─────► "Hello"

second ─────► "Hi"

The original "Hello" string was never changed.

---

9. Strings vs Arrays

Compare these two examples.

Array

int[] first = { 10, 20 };
int[] second = first;

second[0] = 99;

Result:

first  → [99, 20]
second → [99, 20]

Both variables point to the same object, and the object itself was modified.

String

string first = "Hello";
string second = first;

second = "Hi";

Result:

first  → "Hello"
second → "Hi"

second was reassigned to another string.

The original string wasn't modified.

This happens because arrays are mutable, while strings are immutable.

---

10. Value Type vs Reference Type at a Glance

Value TypeReference Type
Variable contains its valueVariable contains a reference to an object
Assignment copies the valueAssignment copies the reference
Variables normally act independently after copyingMultiple variables can refer to the same object
Examples: int, bool, char, decimal, structsExamples: arrays, classes, string

For example:

Value type

int a = 10;
int b = a;

b = 20;

Result:

a = 10
b = 20

Reference type

int[] a = { 10 };
int[] b = a;

b[0] = 20;

Result:

a[0] = 20
b[0] = 20

---

11. A Common Interview Question

What is the difference between value types and reference types in C#?

A good beginner-level answer is:

A value-type variable contains its value directly. When assigned to another variable, the value is copied. A reference-type variable holds a reference to an object. When assigned to another variable, the reference is copied, so both variables can refer to the same object.

You can demonstrate it with:

int x = 10;
int y = x;

y = 50;

Console.WriteLine(x); // 10

Compared with:

int[] x = { 10 };
int[] y = x;

y[0] = 50;

Console.WriteLine(x[0]); // 50

---

12. Final Mental Model

Instead of memorizing definitions, remember these two pictures.

For a simple value-type example:

int a = 10;
int b = a;

Think:

a → 10
b → 10

Two independent values.

For a reference-type example:

int[] a = { 10, 20 };
int[] b = a;

Think:

a ──┐
    ▼
 [10, 20]
    ▲
b ──┘

Two variables referring to the same object.

That simple mental model explains a large part of how variables behave in everyday C# programming.

---

Key Takeaways

  • A variable has a name, type, and value.
  • int, bool, char, and decimal are examples of value types.
  • Arrays and classes are reference types.
  • string is a reference type, but strings are immutable.
  • var lets the compiler infer the type; it does not make C# dynamically typed.
  • Assigning a value type copies its value.
  • Assigning a reference type copies its reference.
  • Two reference variables can therefore refer to the same object.
  • Modifying a shared object is different from reassigning one of the variables.

Once this concept becomes clear, topics such as methods, objects, classes, collections, `ref`, `out`, nullable types, and memory management become much easier to understand.

Comments

Join the discussion. Please keep comments respectful and relevant.

Loading comments...