In this article, we are going to learn how to initialize the parameters of a record type in C#. For an overview of what records are, have a look at this article.

To download the source code for this article, you can visit our GitHub repository.

So, let’s dive in.

How to Initialize Parameters of a Record

Let’s assume we declare a simple record with two parameters. We use the constructor to set the value of the parameters:

Support Code Maze on Patreon to get rid of ads and get the best discounts on our products!
Become a patron at Patreon!
public record Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }
}

The syntax to declare the record is very similar to how we would declare a class but uses the record keyword instead of class. To initialize the parameters of the Person record, the syntax is also similar to initializing those in a class:

var person = new Person("Joe", "Bloggs");

How to Initialize Parameters of a Record Using Positional Parameters

In the previous example, the properties of the record were mutable. One of the reasons to use records is that their properties can be immutable using the init keyword. This means we can only set the value of a property during construction:

publicĀ stringĀ FirstNameĀ {Ā get;Ā init;Ā }
public string LastName { get; init; }

Alternatively, we can achieve the same with a single line of code using the primary constructor:

public record Person(string FirstName, string LastName);

When we use a primary constructor with a record that has parameters, the compiler creates an immutable backing public property for each of our parameters. We call these parameters positional parameters.

It might look slightly unusual that the parameters have Pascal case, not Camel case. This is intentional though, since the compiler will use the exact case of the parameters to generate the backing properties. So if we want to maintain Pascal case properties, we need to use Pascal case parameters.

To instantiate the record, we use the same syntax:

var person = new Person("Joe", "Bloggs");

A More Advanced Example With a Default Value

Now, let’s see what happens if we add an optional parameter called friends to our Person record:

public record Person 
{ 
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public IEnumerable<string> Friends { get; set; }

    public Person(string firstName, string lastName, IEnumerable<string>? friends = null)
    { 
        FirstName = firstName; 
        LastName = lastName;
        Friends = friends ?? new List<string>();
    }
}

In this case, if the person has some friends, we can pass this into the constructor when instantiating the record:

var person = new Person("Joe", "Bloggs", new List<string> { "Alice", "Bob"});

We set the Friends property in our constructor. If the person has no associated friends, we can either pass a null into the constructor or omit it completely since it is an optional parameter. In this case, the Friends property is set to an empty list in the constructor.

However, again there is a much more concise way of declaring our record type using a primary constructor:

public record Person(string FirstName, string LastName, IEnumerable<string>? Friends = null)
{
    public IEnumerable<string> Friends { get; init; } = Friends ?? new List<string>();
};

The FirstName and LastName properties are generated by the compiler as we saw before. With the Friends parameter, the compiler would normally create a backing property for us, with the default value of null, not an empty list.

Instead, we can create the property ourselves and ensure it is set to an empty list if Friends is null. We also make it immutable by using the init keyword.

Conclusion

We initialize parameters for a record type in a similar way to how we initialize parameters for classes.

We have also seen that the compiler automatically creates properties when we use a primary constructor with records which can simplify our code. Finally, we have seen how we set a default value for a property in a more complicated case.

Liked it? Take a second to support Code Maze on Patreon and get the ad free reading experience!
Become a patron at Patreon!