C# records, with-expressions, and value semantics

A record is a type designed for data. A positional record such as Point(int X, int Y) generates properties, a constructor, value-based equality, a readable ToString, and a Deconstruct method. Two records are equal when their fields are equal, even though they are different objects, unlike plain classes where == compares references by default.

C#
using System;

record Point(int X, int Y);

struct Counter {
  public int Value;
}

class Box {
  public int Value;
}

class Program {
  static void Main() {
    var a = new Point(1, 2);
    var b = new Point(1, 2);
    Console.WriteLine(a == b);
    Console.WriteLine(ReferenceEquals(a, b));
    Console.WriteLine(a);

    var c = a with { Y = 5 };
    Console.WriteLine(c + " " + a);

    var (x, y) = c;
    Console.WriteLine(x + " " + y);

    var s1 = new Counter { Value = 1 };
    var s2 = s1;
    s2.Value = 99;
    var c1 = new Box { Value = 1 };
    var c2 = c1;
    c2.Value = 99;
    Console.WriteLine("struct copy: " + s1.Value + ", class alias: " + c1.Value);
  }
}
Read the full lesson