What is non-destructive mutation in C# 9.0?
Non-destructive mutation provides a way to change immutable properties and fields of a record type. This is achieved by using the with expression, which creates a copy of the record type and replaces the existing values with the specified values in the copy.
Explanation
The compiler employs the copy constructor and the clone method to implement the non-destructive mutation of the record types. To customize the copy behavior, the users can write their own copy constructors, in which case the compile will not create a copy constructor.
The positional properties or properties created using standard property syntax work with the with expression. The non-positional properties with the init and set accessors also work with the with expression.
The copy of the record is a shallow copy. This means that for reference-type properties, only the reference is copied, and both the record type and its copy point to the same entity.
Example
The following example demonstrates how to use the with expression to create copies of the record and mutate properties.
- The program creates an object
student1and creates its copystudent2using thewithexpression. - The program first changes
FirstNameto Mark and then theMarksto 50. - The second and third outputs display the changed values for the
FirstNameandMarksfields. - The
==operator returns false in line 26 because the field values are different forstudent1andstudent2. - The
==operator returns true in the output of line 30 because the field values in the new copystudent2are identical to the field values ofstudent1.
The
==operator measures value equality in the record by default.
using System;public class Program{public record Student(string FirstName, string LastName){public int Marks { get; init; }}public static void Main(){// create an objectStudent student1 = new("Sam", "Johnson") { Marks = 100 };// display objectConsole.WriteLine(student1);// create a copy of the objectStudent student2 = student1 with { FirstName = "Mark" };Console.WriteLine(student2);// change a non positional propertystudent2 = student1 with { Marks = 50 };Console.WriteLine(student2);// display the two objects are differentConsole.WriteLine(student1 == student2);// create a copy with identical fieldsstudent2 = student1 with { };Console.WriteLine(student1 == student2);}}
Output
Student { FirstName = Sam, LastName = Johnson, Marks = 100 }
Student { FirstName = Mark, LastName = Johnson, Marks = 100 }
Student { FirstName = Sam, LastName = Johnson, Marks = 50 }
False
True
Free Resources