Question Details

No question body available.

Tags

c# constructor initialization field record

Answers (1)

Accepted Answer Available
Accepted Answer
June 15, 2025 Score: 3 Rep: 7,772 Quality: High Completeness: 80%

While the official documentation doesn't mention/warn about this behavior:

If you need different copying behavior, you can write your own copy constructor in a record class. If you do that, the compiler doesn't synthesize one. Make your constructor private if the record is sealed, otherwise make it protected.

it is still expected per the feature specification

The purpose of the copy constructor is to copy the state from the parameter to the new instance being created. This constructor doesn't run any instance field/property initializers present in the record declaration.

It seems that the design was supposed to remove all normal compiler injections in this method - such as calls to base constructors, so it's fully manually written:

The first thing the constructor must do, is to call a copy constructor of the base, or a parameter-less object constructor if the record inherits from object. An error is reported if a user-defined copy constructor uses an implicit or explicit constructor initializer that doesn't fulfill this requirement.

This latter requirement seems to have been relaxed at some point in the case where we don't have inheritance, i.e. we don't need explicit :base() for object, and the compiler helps us there in our case (.NET6+):

IL0000: ldarg.0
// (no C# code)
IL0001: call instance void [System.Runtime]System.Object::.ctor() / 0A00001C /
IL0006: nop
// Console.WriteLine("---our cloning method---");
IL0007: nop
IL_0008: ldstr "---our cloning method---" / 7000000B /

However, in the case with field initializers and auto-properties such as

public int MyProperty { get; set; } = 42;

we have to remember to include/think about this field initialization logic for the custom copy constructors we write, because it is NOT automatically included at the beginning of the constructor method body as of normal constructors.