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); // 99Reference 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 runtimeModern 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);
}