Using Records In C# 9.0

Introduction

 
In today’s article we will look at records. This is a new feature in C# 9.0. C# 9.0 has been introduced with .NET 5.0. We will look at what records are, how they work, the advantage to having records, and how they differ from classes and structs.

What are Records?

 
Microsoft recently announced the availability of .NET 5 release candidate at Microsoft Ignite 2020. This included the latest features in C# 9.0. In order to code in .NET 5.0, we would need to install the latest preview of Visual Studio 2019 (Version 16.8.0 Preview 3.1). As I had read about some cool features in C# 9.0 including my favorite “Records”, I downloaded and installed the required version as below,
 
Using Records In C# 9.0 

Using Records

 
What exactly are records? Well, to understand this let us see what the difference between classes and structs. As we know, classes are passed around by reference whereas for structs we need to make a copy to pass it around. However, for structs comparisons for equality are based on values, whereas for classes comparisons for equality are based on the reference the class is pointing to. Hence, two classes might have the exact same content but as their references are different, they will not be considered equal. We would have to implement custom code for comparing elements in a class. This is where records come in and give us the best of both worlds. They are immutable, can be passed around by reference and are compared based on their contents. Let us see them in action.
 
Let us create a console application in Visual Studio 2019 (Version 16.8.0 Preview 3.1) as below,
 
Using Records In C# 9.0
 
Using Records In C# 9.0
 
Using Records In C# 9.0
 
Next, we will change the properties of the project and set the Target Framework to .NET 5.0, as below,
 
Using Records In C# 9.0
 
Now add the below code,
  1. using System;  
  2. namespace ConsoleApp Records {  
  3.     public class Program {  
  4.         static void Main(string[] args) {  
  5.             //Classes  
  6.             var employeeClass = new EmployeeClass();  
  7.             employeeClass.Id = 1;  
  8.             employeeClass.EmpName = "John Smith";  
  9.             employeeClass.Salary = 1000;  
  10.             var secondEmployeeClass = new EmployeeClass();  
  11.             secondEmployeeClass.Id = 1;  
  12.             secondEmployeeClass.EmpName = "John Smith";  
  13.             secondEmployeeClass.Salary = 1000;  
  14.             Console.WriteLine(employeeClass == secondEmployeeClass ? "employeeClass is equal to secondEmployeeClass" : "employeeClass is not equal to secondEmployeeClass");  
  15.             //Records  
  16.             var employeeRecord = new Employee();  
  17.             employeeRecord.Id = 1;  
  18.             employeeRecord.EmpName = "John Smith";  
  19.             employeeRecord.Salary = 1000;  
  20.             var secondEmployeeRecord = new Employee();  
  21.             secondEmployeeRecord.Id = 1;  
  22.             secondEmployeeRecord.EmpName = "John Smith";  
  23.             secondEmployeeRecord.Salary = 1000;  
  24.             var thirdEmployeeRecord = new Employee();  
  25.             thirdEmployeeRecord.Id = 2;  
  26.             thirdEmployeeRecord.EmpName = "John Smith";  
  27.             thirdEmployeeRecord.Salary = 1000;  
  28.             Console.WriteLine(employeeRecord == secondEmployeeRecord ? "employeeRecord is equal to secondEmployeeRecord" : "employeeRecord is not equal to secondEmployeeRecord");  
  29.             Console.WriteLine(employeeRecord == thirdEmployeeRecord ? "employeeRecord is equal to thirdEmployeeRecord" : "employeeRecord is not equal to thirdEmployeeRecord");  
  30.             //Updating Records  
  31.             var updatedEmployee = employeeRecord with {  
  32.                 Salary = 2000  
  33.             };  
  34.             Console.WriteLine(employeeRecord == updatedEmployee ? "employeeRecord is equal to updatedEmployee" : "employeeRecord is not equal to updatedEmployee");  
  35.             Console.ReadKey();  
  36.         }  
  37.     }  
  38.     public record Employee {  
  39.         public int Id {  
  40.             get;  
  41.             set;  
  42.         }  
  43.         public string EmpName {  
  44.             get;  
  45.             set;  
  46.         }  
  47.         public double Salary {  
  48.             get;  
  49.             set;  
  50.         }  
  51.     }  
  52.     public class EmployeeClass {  
  53.         public int Id {  
  54.             get;  
  55.             set;  
  56.         }  
  57.         public string EmpName {  
  58.             get;  
  59.             set;  
  60.         }  
  61.         public double Salary {  
  62.             get;  
  63.             set;  
  64.         }  
  65.     }  
  66. }  
In the above code, we first create two classes with the same values of each member. However, these will not be returned as equal as they point to separate references.
 
Then, we create two records in which the members have the same values. These will be returned as equal. For further testing we create a third record which has a member (Id) with a different value. Now, when we compare this record with the first one, they are considered different as the values of the members are not the same.
 
Finally, we see how to create a new record from an existing one with a value of one member changed. This will create a new record and the old one will have the same previous value. We can then compare and see that they are considered different.
 
We can execute the code and confirm our results,
 
Using Records In C# 9.0
 

Summary

 
In this article, we looked at records which are a new feature in C# 9.0. The main advantage of using records is that they are immutable and when passed in a state to some function are guaranteed to stay in the same state. Happy Coding!