Records, Anonymous Types, and Non-Destructive Mutation
Tags: csharp, programming, dotnet, cleancode
Published: 2023-08-23 15:13:35

---
title: Records, Anonymous Types, and Non-Destructive Mutation
published: true
date: 2022-09-10 00:00:00 UTC
tags: csharp,programming,dotnet,cleancode
canonical_url: https://www.milanjovanovic.tech/blog/records-anonymous-types-non-destructive-mutation
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ukcjyrfb03rzh0zj11is.png
---

Today, I'm going to share some fascinating things you can do with records and anonymous types. I will introduce you to the concept of non-destructive mutation. And I will talk about when and why we might want to use this C# language feature.

## What Is a Record?

With **C# 9** we can use **records** that are a new reference type. **C# 10** introduced record structs so that you can define records as value types. Records are distinct from classes in that record types use value-based equality.

Let's see how we would define a `record`:

```csharp
public record Food(string Name, double Price);
```

This way of declaring a `record` is called a positional record. The constructor we have defined here is called the **primary constructor**.

The `Name` and `Price` properties are init only properties, meaning they can only be set in the constructor or using a property initializer.

Since our properties are init only, is there any way to change their value?

## Non-Destructive Mutation Using The With Expression

We said we can't modify the properties of our `record`, because the properties are init only. However, we can use the `with` expression (introduced in **C# 9** ) to create a new instance of our record with modified values.

Let's see how we would use the `with` expression:

```csharp
var banana = new Food("🍌", 1.95);

var bananaOnSale = banana with
{
    Price = 0.99
};
```

It's important to highlight two things here:

- The original banana instance remains unchanged
- The `with` expression creates a new record instance with only the `Price` property modified

I mentioned Anonymous Types in the title, so let me show you something interesting you can do with them.

## Anonymous Types And Non-Destructive Mutation

Did you know that you can use the `with` expression with anonymous types?

Just a reminder that the `with` expression is available from **C# 9** and later.

Let's create an anonymous type:

```csharp
var apple = new
{
    Name = "🍎",
    Price = 1.21
};
```

This is how we can modify it using the with expression:

```csharp
var orange = apple with
{
    Name = "🍊"
};
```

And again the same rules apply:

- The original apple instance remains unchanged
- The with expression creates a new anonymous type instance with only the Name property modified

I found this feature useful in LINQ method chains.

For example, loading an anonymous type from the database where some properties have a default value. You can then use this feature to calculate the values for these properties in memory.

* * *

**P.S. Whenever you're ready, there are 2 ways I can help you:**

1. [**Pragmatic Clean Architecture:**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting) This comprehensive course will teach you the system I use to ship production-ready applications using Clean Architecture. Learn how to apply the best practices of modern software architecture. [**Join 950+ students here.**](https://www.milanjovanovic.tech/pragmatic-clean-architecture?utm_source=dev.to&utm_medium=website&utm_campaign=cross-posting)

2. [**Patreon Community:**](https://www.patreon.com/milanjovanovic) Think like a senior software engineer with **access to the source code** I use in my YouTube videos and **exclusive discounts** for my courses. [**Join 820+ engineers here.**](https://www.patreon.com/milanjovanovic)