
Immutability is a concept that has been widely adopted in several programming languages. C# has been patiently waiting for a dedicated feature for this, and records are here!
In this article, we will explore C# records, ratify every myth and question surrounding records and classes, delve into the C# record constructor, reflect on inheritance, and understand how private records work in .NET. Let's go!
C# Records
Ever stumbled upon a piece of code filled with boilerplate just to make a class immutable? Good news; C# records to the rescue!
What are C# Records?
C# Records are a new kind of type declaration – they’re similar to classes, but they’re suited for developing immutable data models out of the box. Records, to put it simply, can be summarized asSimple-Immutables-Simplified.
Consider the following Record:
publicrecordPerson(stringName,intAge);
You’ve just defined an immutable type named ‘Person’ with two properties, ‘Name’ and ‘Age’. That was easy, wasn’t it?
The Syntax of C# Records
The simple syntax of a record is yet another of its perks. Just like ‘classes’ and ‘structs’, you can declare ‘records’ with properties, methods, and events.
publicrecordCar{publicstringBrand{get;init;}publicstringModel{get;init;}}
The ‘init’ keyword ensures the properties are immutable, i.e., once assigned, they can’t be changed.
But you might be wondering,what about value equality? Here’s another cool thing about records – they bring ‘value equality’ into play, rather than ‘reference equality’, which conventional classes use.
Delving into the Details: C# Record Types
Let’s break it down and dive deeper into the abyss of C# Record types.
Understanding the Structure of C# Record Types
Here’s the code-example illustrating the structure and key elements of a C# Record.
publicrecordEmployee{publicstringName{get;init;}publicstringDepartment{get;init;}publicEmployeeManager{get;init;}}
In this case, the Employee record consists of three properties. ‘Name’ and ‘Department’ are self-explanatory, but ‘Manager’ is a nested declaration within the Employee record – an Employee type inside Employee.
When to Use C# Records
Record in C# should be used when:
- You need a type primarily defined by its data, and this data is immutable.
- You need value equality – “Are these two things the same?” rather than “Are they the same object?”
So, isn’t it splendid how records encapsulate the essence of object-oriented programming? They’re quite the game-changer!
C# Record vs Class: A Comprehensive Reality Check
As Coders, we grapple with design decisions every day. Such a common predicament is when to use a class and when to opt for a record in C#. The fascinating world of programming languages is full of such dilemmas, and each choice can parley into diverse results.
Distinguishing the Functionality: C# Record vs Class
Indeed, C# records and classes are akin but have distinctive behaviours, especially around immutability and equality. But how about we get our hands dirty and write some code to unravel the differences?
publicclassCountryClass{publicstringName{get;set;}publicstringContinent{get;set;}}publicrecordCountryRecord(stringName,stringContinent);CountryClasscountry1=newCountryClass{Name="Germany",Continent="Europe"};CountryClasscountry2=newCountryClass{Name="Germany",Continent="Europe"};Console.WriteLine(country1==country2);// Output: False
The comparison of country1 & country2 returns false even though they have identical properties. It’s because classes in C# compare references, not the contents.
Now, let’s contrast this with records:
CountryRecordcountryRecord1=newCountryRecord("Germany","Europe");CountryRecordcountryRecord2=newCountryRecord("Germany","Europe");Console.WriteLine(countryRecord1==countryRecord2);// Output: True
Wowza, it returnstrue
. So, records in C# are different – they factor in the contents for comparison, not just reference! They are immutable and possess value semantics. Ain’t that nifty?
Realistic Use-Case Scenario: C# Record vs Class
Remember our old friend, the Product Catalogue, in an e-commerce application? Here’s where our recently learned knowledge comes into play. Let’s consider two classes, ProductClass and ProductRecord:
publicclassProductClass{publicstringProductName{get;set;}publicstringDescription{get;set;}publicdecimalPrice{get;set;}//...more properties}publicrecordProductRecord(stringProductName,stringDescription,decimalPrice);
For largely immutable entities like a product catalogue, employing records makes sense. You get a concise, immutable object with equal-to and copy semantics out of the box. You can also update properties using thewith
keyword while retaining the immutability:
varbaseProduct=newProductRecord("Book","It's a book, duh!",10m);vardiscountedProduct=baseProductwith{Price=9m};
However, when objects require mutable state, classes still emerge victoriously. Imagine a Shopping Cart class in the same e-commerce application. You continually add, remove items, indicating a frequent change of state. Leveraging classes here is more fitting.
Each tool has its place. Isn’t that the philosophy of good programming?
Recorder C#: Automated Testing
We, coders, often find ourselves in a bind when dealing with UI tests. Wouldn’t it be great if we could just record our browser interactions and convert them into C# code for WebDriver-based UI tests? Well, that’s precisely what Recorder C# does for you!
vardriver=newChromeDriver();varrecorder=newRecorder(driver);recorder.Start();driver.Navigate().GoToUrl("http://www.yoursite.com");//...do your testingrecorder.Stop();
TheStart
method tells the recorder to start recording and theStop
method to stop. The rest is all your interactions with the UI!
Mastering the C# Record Constructor
A constructor’s primary function is to initialize the object of a class. But in C# records, a constructor does more than that!
Streamlining Constructors with C# Records
Records break the traditional mould of constructors. Just look at this tidy piece of code!
publicrecordEmployee(stringName,stringDepartment);
Here, in merely one line of code, you’ve given birth to a record with a constructor accepting two parameters and associating them to the read-only characteristics of the object. Talk about efficiency!
Crafting a C# Record Constructor
However, if your constructor requires additional logic or even validation of parameters, records can cover that too:
publicrecordEmployee{publicEmployee(stringname,stringdepartment){if(string.IsNullOrEmpty(name))thrownewArgumentNullException(nameof(name));if(string.IsNullOrEmpty(department))thrownewArgumentNullException(nameof(department));Name=name;Department=department;}publicstringName{get;}publicstringDepartment{get;}}
Need to validate input? You can add validation checks right inside the constructor. It’s like having your cake and eating it too (figuratively speaking)!
Understanding C# Record Inheritance
The Concept: C# Record Inheritance
Records inherit from other records. How cool is that? Records use the keyword ‘record’ instead of ‘class’ for inheritance. Take a look:
publicrecordVehicle{publicstringBrand{get;init;}}publicrecordTruck:Vehicle{publicintTowingCapacity{get;init;}}
Here, ‘Truck’ record is inheriting from the ‘Vehicle’ record. Talk about keeping the lineage clean!
Taking Advantage of C# Record Inheritance
Remember, records are sealed by default. If you want to allow other records to inherit from a base record, be sure to include thesealed
modifier:
publicsealedrecordVehicle{publicstringBrand{get;init;}}
It’s stunning how much thought is put into extending and improving C# towards a more immutable future!
C# Record Property: Tweaking and Modifying
Let’s shed some light on how you can tweak and modify properties in C# Records.
Blessing of Immutability: C# Record Change Property
Records in C# are immutable, but there are times when you need a copy of a record with one or more properties modified. C# Record has the ‘with’ keyword for this. Magic, isn’t it?
publicrecordPerson(stringName,intAge);Personbob=newPerson("Bob",30);PersonbobTwin=bobwith{Name="Bob's Twin"};// New person with age 30
Here,bobTwin
is a new record, based on Bob, but it’s not Bob. Mind=blown!
Decoding the Differences: C# Record vs Record Struct
To struct, or not to struct, that’s the conundrum!
Understanding the Key Distinctions
So what’s the brass tacks of C# Record and Record Struct? The essential difference is that by design, recordclass
types use reference semantics for equality while recordstruct
types use value semantics for equality.
Making the Right Choice: C# Record vs Record Struct
When faced with the choice between recordclass
and recordstruct
, always go for the one that fits your scenario. When in doubt, favor recordclass
. The semantics of a reference type better align with how data models are typically used.
Exploring Private Records in .NET
Private Records in C#: An introduction
Ever wished for private record types in C#? Your wish is C#’s command! This incredible addition of private accessibility modifier to record types makes things immeasurably simpler.
Application and Use Cases of Private Records in .NET
A private record is useful when seeking to encapsulate operations within a type, and its details play no role in its public API. This makes it an ideal candidate for implementing Data Transfer Object (DTO) patterns and encapsulating algorithms.
Congratulations, folks! You’ve made it to the end of this enthralling journey through the vast landscape of C# records. We’ve covered everything from the basics, to scenarios for usage, to comparisons with classes, and we’ve even touched on C# Record Constructors, inheritance, property changes, and private records in .NET.
Now, it’s time for you to apply these concepts and take advantage of this wonderful feature of C#.
Remember, though records are awesome, they’re not a silver bullet for all scenarios. Sometimes, classes or structs might be just what you need.
Think it through, always opt for the simplest solution that meets your need.
Top comments(4)

- LocationParis, France
- EducationESIEA, Gobelins
- Joined
very nice article, thx !!
But I don"t really understand why the part "Recorder C#: Automated Testing" is here (even if it is interesting)
and the end, record struc vs record class should be better explained, IMHO.
thx again anyway !! :)

- LocationParis, France
- EducationESIEA, Gobelins
- Joined
I ask question to Copilot. Here are the response. Could help other people.
The difference between a record class and a record struct in C# mainly revolves around whether they are reference types or value types:
Record Class:
- Reference Type: This means that when you create an instance of a record class, it is stored on the heap, and variables hold a reference to the memory location.
- Immutability: By default, record classes are immutable, meaning their properties cannot be changed after they are created. However, you can make them mutable if needed.
- Usage: Use record classes when you need to represent complex data structures that benefit from reference semantics, such as when you need to share data between different parts of your program.
Record Struct:
- Value Type: This means that instances of record structs are stored on the stack (if they are local variables) or inline within other objects, and variables hold the actual data.
- Mutability: Record structs are mutable by default, but you can make them immutable by using the readonly keyword.
- Usage: Use record structs for small, lightweight data structures that benefit from value semantics, such as when you need to pass data around without the overhead of heap allocation.
In summary, choose record classes for more complex, reference-based data structures and record structs for simpler, value-based data structure
After that, I asked :
I thought that records were immutable. Why record structs are mutable by default ?
That's a great question! While records in C# are often associated with immutability, the default mutability ofrecord structs is due to their nature as value types.
Here's a bit more detail:
Record Classes: These are reference types and are immutable by default. This immutability is a key feature that helps ensure that the data they hold cannot be changed after creation, which is useful for creating reliable and predictable data structures.
Record Structs: These are value types and are mutable by default. This default mutability is because value types are typically used for small, simple data structureswhere performance is critical, and the overhead of creating new instances for every change can be significant. However, you can make record structs immutable by using the
readonly
keyword.
If you want to make a record struct immutable, you can define it like this:
publicreadonlyrecordstructPoint(intX,intY);
This way, the propertiesX
andY
cannot be changed after thePoint
is created.

- LocationBrazil
- PronounsHe / Him
- Joined
Top, very nice and helpful !
Thanks for sharing. ✅
For further actions, you may consider blocking this person and/orreporting abuse