Why is an explicit `this` constructor initializer required in records with a primary constructor?

This is because primary constructor parameters are a little bit special – they are in scope throughout initialization of the record. Guess what the following program prints:

System.Console.WriteLine(new Foo(Bar: 42).Baz);

public record Foo(int Bar) {
    public int Bar => 41;
    public int Baz = Bar;
}

41 or 42?

And the answer is…

drumroll please…

42!

What’s going on here?

During the initialization of the record, any references to Bar don’t refer to the property Bar, but to the primary constructor parameter Bar.

What this means is that the primary constructor must be called. Otherwise what would happen in this case:

System.Console.WriteLine(new Foo().Baz);

public record Foo(int Bar) {
    public Foo(){}
    public int Bar => 41;
    public int Baz = Bar; //  What is Bar here when the primary constructor isn't called.
}

Aside

The Bar parameter is only in scope during initialization. After initialization the Bar property is in scope instead. If we were to change our example ever so slightly:

System.Console.WriteLine(new Foo(Bar: 42).Baz);

public record Foo(int Bar) {
    public int Bar => 41;
    public int Baz => Bar; //Note this is `=>` not `=`
}

It would print 41.

Leave a Comment