Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 79 additions & 1 deletion docs/articles/mapping/Data-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,77 @@ var dict = point.Adapt<Dictionary<string, int>>();
dict["Y"].ShouldBe(3);
```

## Record types

>[!IMPORTANT]
> Mapster treats Record type as an immutable type.
> In this regard, only a with-like non-destructive mutation is available.
Comment on lines +100 to +101
Copy link
Contributor Author

@DocSvartz DocSvartz Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mapster treats the Record type as an immutable type.
Only a non-destructive mutation returned new modify record instance.

@stagep Maybe like this?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the result is a Record then the

"A non-destructive mutation" is correct English but the remaining part makes no sense as it is English words but used incorrectly. "A non-destructive mutation is returned" is also correct but "new modify record instance" is not. Do you mean a "newly modified record instance"? That is English but ambiguous.

Copy link
Contributor Author

@DocSvartz DocSvartz Mar 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stagep Ok, Then we will use the original definition from the official wiki.

Only a Nondestructive mutation - creating a new object with modified properties.

>
> ```csharp
> var result = source.adapt(data)
>//equal var result = data with { X = source.X.Adapt(), ...}
>```
### Features and Limitations:
# [v10.0](#tab/Records-v10)
>[!NOTE]
> By default, all [C# Records](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record) are defined as a record type.
> Limitations by count of constructors and constructor parameters used in Mapster version 7.4.0 do not apply.
#### Using default value in constuctor param
If the source type does not contain members that can be used as constructor parameters, then will be used the default values ​​for the parameter type.
Example:
```csharp
class SourceData
{
public string MyString {get; set;}
}
record RecordDestination(int myInt, string myString);
var result = source.Adapt<RecordDestination>()
// equal var result = new RecordDestination (default(int),source.myString)
```
#### MultyConsturctor Record types
If there is more than one constructor, by default, mapping will be performed on the constructor with the largest number of parameters.
Example:
```csharp
record MultiCtorRecord
{
public MultiCtorRecord(int myInt)
{
MyInt = myInt;
}
public MultiCtorRecord(int myInt, string myString) // This constructor will be used
: this(myInt)
{
MyString = myString;
}
}
```
# [v7.4.0](#tab/Records-v7-4-0)
>[!NOTE]
>Record type must not have a setter and have only one non-empty constructor, and all parameter names must match with properties.
Otherwise you need to add [`MapToConstructor` configuration](xref:Mapster.Settings.ConstructorMapping#map-to-constructor).
Example for record types:
```csharp
Expand All @@ -110,5 +181,12 @@ class Person {
var src = new { Name = "Mapster", Age = 3 };
var target = src.Adapt<Person>();
```
---
### Support additional mapping features:
There are limitations to map Record type automatically. Record type must not have a setter and have only one non-empty constructor, and all parameter names must match with properties. Otherwise you need to add [`MapToConstructor` configuration](xref:Mapster.Settings.ConstructorMapping#map-to-constructor).
| Mapping features | v7.4.0 | v10.0 |
|:-----------------|:------:|:-----:|
|Custom constructor mapping| - ||
|Ignore| - ||
|IgnoreNullValues| - ||
Loading