1class Account {2 public string Owner;3 public int Balance;4 public Account(string o)5 => Owner = o;6 public void Deposit(int x)7 => Balance += x;8}locals$ dotnet run751var a = new Account("Ada");2a.Deposit(50);3var b = a;4b.Deposit(25);5var c = new Account("Bo");6Console.WriteLine(a.Balance);heapabc#1AccountOwnerBalance#2AccountOwnerBalancenew"Ada""Bo"#1#2+50+2575
Code cards: the class (Account.cs) and the program (Program.cs)Memory: variables hold references; objects live on the heapTokens: new, values and references moving; arrows show which object a variable refers toLeft: the class Account.cs (the blueprint) and Program.cs, which uses it. Right: the variables a, b and c, the heap with the objects, and the console. new makes an object on the heap with default fields, the constructor sets Owner, and the variable gets a reference (an arrow). b = a copies the reference, so a deposit through b shows through a, and the console prints 75. The figure writes a reference as #1 or #2. A real reference is the object's address in memory, which C# never shows you; you only follow it with the dot, as in a.Balance.

The class

  1. A class describes a kind of object. Account.cs says every Account has two fields, Owner and Balance, plus a constructor and a method, Deposit. The class itself holds no account data: it is a blueprint, and a type.

Making an object

References and sharing

What happens

// step 1/10 · blueprint
1  class Account {              a new type, named Account
2    public string Owner;       field: every Account has an Owner
3    public int Balance;        field: and a Balance
4    public Account(string o)   the constructor: named after the class
5      => Owner = o;            sets this object's Owner
6    public void Deposit(int x) a method
7      => Balance += x;         adds x to this object's Balance
8  }                            end of the class

field        a variable that belongs to each object
public       code outside the class may use it (members are private by default)

The figure writes a reference as #1 or #2. A real reference is the object's address in memory, which C# never shows you; you only follow it with the dot, as in a.Balance. Here a, b and c are local variables of the top-level statements, so they normally sit in the method's stack frame. Where a local lives is a runtime detail; what matters is that it holds a reference, not the object.