C# · Lesson 2

Value, reference, and the danger of null

Today’s win: predict whether assignment copies the value itself or copies a reference to the same object.

The first-principles model

A variable slot either directly contains a small value, or it contains a reference that points to an object somewhere else.

In C#, types such as int, bool, decimal, DateTime, and most structs are value types. Classes, strings, arrays, lists, and most objects you create with new SomeClass(...) are reference types.

Value types copy the value

When you assign an int to another variable, you get another int value. Changing one variable does not change the other.

var a = 10;
var b = a;

b = 99;

Console.WriteLine(a); // 10
Console.WriteLine(b); // 99

Reference types copy the reference

When you assign a class instance to another variable, you usually copy the reference. Both variables can point at the same object.

var first = new Person("Ada");
var second = first;

second.Name = "Grace";

Console.WriteLine(first.Name);  // Grace
Console.WriteLine(second.Name); // Grace

class Person
{
    public string Name { get; set; }

    public Person(string name)
    {
        Name = name;
    }
}

first and second are separate variable slots, but the copied reference points to the same Person object.

Where null enters

A reference variable can sometimes point to nothing. That nothing is null. If you access a member through null, your program can throw a NullReferenceException.

string name = null; // warning with nullable reference types enabled

Console.WriteLine(name.Length); // possible crash at runtime

Modern C# wants you to state uncertainty

With nullable reference types enabled, string means “I expect a real string”, while string? means “this might be missing.” The compiler then pushes you to check before using it.

string? maybeName = FindName();

if (maybeName is not null)
{
    Console.WriteLine(maybeName.Length);
}