Make computed property be calculated once in immutable record types

1.3k Views Asked by At

I was making an immutable record type with a computed property like this:

public record Example
{
    public int A { get; init; }
    public int B { get; init; }
    public int C => A * B;
}

Knowing that record field setters are init only, the value of example.C should never change for the lifespan of an example object.

In the example above, the computation behind the C property is very trivial, but for types with compute-intensive properties, caching could affect the speed of a program. Is there a simple way to make the property be calculated only once? Should it not be a default for immutable record types?

Of course one can abandon the idea of computed properties and do the computation in the constructor:

public record Example
{
    public int A { get; init; }
    public int B { get; init; }
    public int C { get; private init; }
    
    public Example(int A, int B)
    {
        C = A * B;
    }
}

But is there a way to do it without a constructor?

3

There are 3 best solutions below

1
Voxpire On BEST ANSWER

I often use this pattern to lazily initialize expensive values that may or may not ever be referenced.

public record Example
{
    private int? _C;
    
    public int A { get; init; }
    public int B { get; init; }
    public int C => _C ??= (A * B);
}
0
Brian.Z On

I still recommend using constructor, because code readability and generality. In addition, if the calculation process of the C is complicated, define a private method.

public record Example
{
    public int A { get; init; }
    public int B { get; init; }
    public int C { get; init; }

    public Example(int a, int b)
    {
        A = a;
        B = b;
        C = InitC();
    }
    
    private int InitC()
    {
        return A * B;
    }
}
0
Justas On

Cleaner way:

public record Example(int A, int B)
{
    public int C { get; init; } = A * B;
}