In a previous post I wrote about using records when implementing the builder pattern. I just had another idea that allows you to skip the .Build call when creating your objects.

Example builder:

internal record PersonBuilder
{
    internal PersonBuilder()
    {
        GivenName = "Jane";
        FamilyName = "Doe";
        Age = Random.Shared.Next(18, 101);
        Height = Random.Shared.Next(130, 201);
    }

    internal string GivenName { get; init; }
    internal string FamilyName { get; init; }
    internal int Age { get; init; }
    internal int Height { get; init; }

    internal Person Build()
    {
        return new Person(GivenName, FamilyName, Age, Height);
    }
}

We can create a Person like this:

var person = new PersonBuilder
{
    GivenName = "Josef"
}.Build();

Wouldn't it be nice if we could skip the .Build call at the end?
We can!๐Ÿ˜ƒ

By adding an implicit operator to our builder like this...

public static implicit operator Person(PersonBuilder b) => b.Build();

...we can now use the builder like this:

Person person = new PersonBuilder
{
    GivenName = "Josef"
};

The implicit operator get's invoked since we change from var to Person when declaring our variable. ๐Ÿš€

Full builder:

internal record PersonBuilder
{
    internal PersonBuilder()
    {
        GivenName = "Jane";
        FamilyName = "Doe";
        Age = Random.Shared.Next(18, 101);
        Height = Random.Shared.Next(130, 201);
    }

    internal string GivenName { get; init; }
    internal string FamilyName { get; init; }
    internal int Age { get; init; }
    internal int Height { get; init; }

    internal Person Build()
    {
        return new Person(GivenName, FamilyName, Age, Height);
    }
    
    public static implicit operator Person(PersonBuilder b) => b.Build();
}