Magnus Mårtensson
Microsoft Regional Director, Azure MVP, CEO Loftysoft
Avirag Jain
Director & CTO R Systems
Mahesh Chand
Founder C# Corner, CEO Mindcracker
Chris Gali
CEO & Co-Founder Graphite
Subinder Khurana
Chief Architect StoryProcess, Founder NASSCOM DeepTech Club
Bryan Rishforth
Investor, Chairman Graphite
Bryn Everson
Director Biz Dev Graphite
Raj Tiwari
Digital Transformation Leader, Futurist and Visionary
Joseph Guadagno
Microsoft MVP, Lead Quicken Loans
Nikita Sachdev
Entrepreneur, Blockchain Enthusiast & Advisor, Social Media Influencer
Doug Wagner
COO & Founder Adapt Technical Group
Ritesh Modi
Architect, Senior Evangelist, Cloud Architect
Crystal Wenrick
Director Communications Mindcracker
Allen O’Neill
Microsoft MVP, Consulting Engineer/Architect
Praveen Kumar
CEO MCN Solutions
Chris Love
Founder Love2Dev, Microsoft MVP, Author
Sanjay Vyas
Microsoft Regional Director, Microsoft MVP, Founder & CEO SkillLabs Technologies
Veena Sarda
Deep Learning Consultant, Author
Sekhar Srinivasan
C# Corner MVP, Microsoft Certified Trainer, Pluralsight Author
Lalit Bansal
Founder & CEO - EIY SYS
Navdeep Garg
CEO Revinfotech
Prakash Tripathi
Tech Manager/Leader, Microsoft MVP, Blogger
Bhavna Jain
Breakthrough Consultant
Naveen Sharma
Enterprise Architect, Leadership Coach, Author
Vidya Vrat Agarwal
Principal Architect, Microsoft MVP, Author
Sheetal Agarwal
Founder Clownselors, Medical Clown, Trainer
Abhishek Kant
Founder GTM Catalyst
Vishnu Saran
Founder & CEO VoiceQube
Sandeep Soni
Founder & CEO Deccansoft, Microsoft Certified Trainer
Parveen Malik
AVP InfoSec & Vulnerability Management, Information Security Expert
Nitin Pandit
Microsoft MVP, Developer Evangelist, Author
Niloshima Srivastava
C# Corner MVP, Tech Architect, Trainer, Blogger
Bala Chirtsabesan
Senior Software Engineer at Microsoft, Author
Manoj Mittal
Sr. Technical Architect, C# Corner MVP, Author
Chandni Di
Co-Founder Voice of Slum
Vithal Wadje
Technical Lead, Microsoft MVP, Author
Shivam Ahuja
Founder SkillCircle, Business Mentor
Chervine Bhiwoo
Solution Architect, Microsoft MVP, Author
Saurabh Jain
Vice President Paytm, Founder Fun2Do Labs, Author
Vinay Solanki
Head IoT at Lenovo, Founder IoT-NCR
Anshu kumari
Founder Blockchainkids, Inventor, Trainer
Amit Singal
CEO Startup Buddy
Dev Pratap
Co-Founder & CEO Voice of Slum
Amey Vartak
Technology Consultant, Full Stack Developer, C# Corner MVP, Author
Viswanatha Swamy
Principal Software Engineer, C# Corner MVP, Author
Sanket Verma
Research Engineer @ Ballistics (Forensics) and Chair, PyData Delhi
Sourabh Somani
Lead Developer, Microsoft MVP, Author
Abhishek Mishra
Software Architect, C# Corner MVP, Author
Siddharth Vaghasia
Technical Consultant, C# Corner MVP, Blogger
Bassam Alugili
Senior Software Specialist, Database Expert
S Ravi Kumar
Solution Architect, C# Corner MVP, Author
Sundaram Subramanian
Full Stack Developer, C# Corner MVP, Speaker
Deepesh Somani
Solution Architect, Microsoft MVP, Author
Debasis Saha
Technical Project Manager, C# Corner MVP, Blogger, Author
Vipul Jain
Software Architect, C# Corner MVP, Author
Akshay Patel
Technical Architect, Microsoft Certified Trainer, C# Corner MVP, Author
Stephen Simon
RPA Developer, Evangelist, Author
Vivek Sharma
Founder Kingster636, AR/VR Specialist
Jeetendra Gund
Technical Lead, C# Corner MVP, Author
Sujal Beniwal
AI Enthusiast, Student
M Viknaraj
Microsoft MVP, Azure Architect, Author
Prasham Sabadra
Software Architect, C# Corner MVP, Trainer, Author
Aakash Maurya
Senior Developer, C# Corner MVP, Speaker
Ankit Sharma
Senior Software Engineer, C# Corner MVP, Author
Mangesh Gaherwar
Team Lead, C# Corner MVP, Author
Viral Jain
Technical Consultant, C# Corner MVP, Author
Bhasker Das
Solution Architect, Evangelist
Manish Dwivedi
Associate Project Manager
Ck Nitin
Programmer, Author
Rohit Gupta
Technical Trainer, Author
Manish Tewatia
Full-stack Marketer, UX Designer
Bhavya Gaur
Technical Illustrator
Rohit Tomar
SEO/SMO Expert
Web Track
Cloud & Data Track
Dev Track
Registration & Breakfast
Future of Desktop Apps with JS (ElectronJs)
Nitin Pandit
Building Serverless Microservices Using Microsoft Azure
Vithal Wadje
Innovating RPA: A Robot for Every Person
Stephen Simon
Managing Cloud Storage Accounts using Logic Apps
Viknaraj Manogararajah
Data visualization using Python
Sekhar Srinivasan
Going Cross platform with AR Foundation
Vivek Sharma
Keynote
Managing your Azure dependencies in ASP.NET Core apps using VS
Bala Chirtsabesan
Securing Applications on Intelligent Azure
Abhishek Mishra
Getting started with Blazor the Framework of Future
S Ravi Kumar
Lunch
Build Progressive Web Apps using Angular 9
Debasis Saha
Build and deploy to any platform using Azure DevOps
Chervine Bhiwoo
Deep Dive in Azure Service Bus
Akshay Patel
Build a Native Mobile Application using React Native and JavaScript
Joseph Guadagno
Making sense of Web Job, Web Job SDK and Functions in Azure
Prakash Tripathi
CloudFront Distribution in AWS
Viral Jain
Tea Break
Introduction to PowerBI
Aakash Maurya
Build Advanced SPFx solutions with React and Graph API
Siddharth Vaghasia
Build Business Intelligence Analyst (BIA) Skills
Sundaram Subramanian
Deep dive of Power Platform – AI BUILDER
Prasham Sabadra
Panel 1
What's new in SharePoint development
Vipul Jain
Build a SSO (Single Sign On) based Native JavaScript application with Microsoft Identity within 10 minutes
Manoj Mittal
Panel 2
Applications and working of AI
Veena Sarda
Deploying serverless API's with .Net core 3.0 on AWS & Azure
Amey Vartak
Panel 3
Blockchain with .NET Core (Ark)
Anshu Kumari
Closing Note & Prize Distribution
Dev Track
Cloud Track
Architecture Track
Emerging Tech Track
Registration & Breakfast
Creating Full-Stack Web Apps Using Server-Side Blazor
Ankit Sharma
Real time face recognition with MS Cognitive Services
Niloshima Srivastava
Building Scalable APIs with GraphQL
Jeetendra Gund
Future of development with AI and Blockchain
Navdeep Garg
Debugging Tips and Tricks with Visual Studio 2019
Joseph Guadagno
Azure Containers
Abhishek Kant
Enterprise Architecture
Naveen Sharma
Bot Framework - learn it fast and look like a boss!
Allen O’Neill
Keynote
.Net Core & C# 8 Performance
David McCarter
Working with Azure kubernetes services
Ritesh Modi
Becoming an Architect
Vidyavrat Agarwal
Why Techies Need to Learn Product Management
Saurabh Jain
Lunch
Build a rules engine in .Net Core
Sanjay Vyas
Building CI and CD Pipeline using Azure DevOps
Sandeep Soni
Entity Framework Core - Tips and Tricks, Performance Optimization, and Tuning
Bassam Alugili
Hacking your way into Data Science
Sanket Verma
Speed up your .Net Core Website
Sourabh Somani
Azure
Magnus Mårtensson
Demystifying Open Distro for Elasticsearch
Suman Debnath
Future of Data
Shivam Ahuja
Tea Break
gRPC with C# and .Net Core
Mangesh Gaherwar
Panel 1
Essentials of Cloud security
Parveen Malik
Power platform and Dynamics 365
Deepesh Somani
Microservices - the gRPC Way
Viswanatha Swamy
Panel 2
Reserved
Reserved
Closing Note & Prize Distribution
Immutable DTOs in C# 12 with Record Types
Data on the wire should not be a moving target. When a value crosses a network boundary, lands in a message queue, or feeds a UI layer, it needs to behave predictably. Mutations midway through that journey are a common source of bugs in distributed systems, particularly along the Sydney-to-Frankfurt latency belt used by many Australian banks.
DTOs — Data Transfer Objects — exist precisely to keep that data stable. They are the carriers between your domain, your service layer, and your external callers. As the .NET ecosystem has matured, the language features for building these carriers have shifted from hand-rolled classes toward something far more ergonomic: record types.
The arrival of C# 12 brought further refinements to the record story. Primary constructors on regular classes, collection expressions, and improved required member enforcement all pair well with records when you want your DTO surface to be both concise and impossible to mutate by accident.
This piece walks through why records became the preferred vehicle for immutable DTOs, how C# 12 sharpens them, and where they are a poor fit. It also touches on practical patterns seen in production codebases from Brisbane to Perth.
The Evolution of DTOs in C#
Before records landed in C# 9, most teams wrote DTOs as plain classes with read-only properties, verbose constructors, and an Equals override they often forgot to update. A single Address DTO could easily run to forty lines, and engineering teams at places like REA Group or Atlassian frequently cited that verbosity as a tax on every API contract review.
Records collapsed that boilerplate into a single line for the simple case. A positional record declares its shape, its constructor, its Deconstruct method, and value-based equality in one expression. That collapse is not just cosmetic — it reduces the surface area where a junior developer can introduce a bug.
The trend continued with C# 10's record struct, and C# 12's primary constructors on classes blurred the line further. Today you can choose between reference records, value records, or a regular class with primary constructor parameters, depending on whether you want identity, value semantics, or a familiar object graph.
Records vs Classes vs Structs
Picking the right type is a design decision, not a stylistic preference. A record class gives you value-based equality and immutability hints, but it still lives on the heap, ships with the same garbage collection profile, and pays the indirection cost of a reference. That profile fits well for DTOs that travel over HTTP or JSON, where the object may be passed around many services.
A record struct is a value type. It can avoid heap allocation entirely when used carefully, but copying grows with the size of the record. For small payloads — a token, a coordinate, a status flag — record structs shine. For a fat Product or Order DTO with embedded lists, the copy cost outweighs the benefit.
Regular classes with the new primary constructor syntax occupy a middle ground. You can mark fields as readonly, keep familiar syntax, and avoid the value-semantics surprises that occasionally catch developers off guard when a record struct is passed into a generic constraint. Each option has a place, and the wrong choice usually shows up as either allocation churn or a flaky test that hinges on reference equality.
Positional Records and required Members
Positional records are the canonical syntax for DTOs in modern C#. You list the members in the parameter list, and the compiler synthesises the property, the field, the constructor, and the deconstructor:
public record OrderDto(string OrderId, string CustomerName, decimal Total);
That single line carries a lot of weight. The OrderId and CustomerName are init-only properties, so they can be set during construction but not after. The Total cannot drift below zero unless you add validation, and equality comparisons between two OrderDto instances compare member by member.
C# 12's refined required keyword now applies to any property — not just records. You can pair it with records to ensure the caller cannot accidentally omit a field:
public record AddressDto(required string Line1, string? Line2, required string Postcode);
The compiler will refuse to build until the caller supplies a Line1 and Postcode. This combination of immutability and requiredness is particularly useful for DTOs that fan out across microservices, where a missing field would otherwise be detected only at runtime in some far-away region.
Pattern Matching and Serialisation
Records pair beautifully with switch expressions. The positional syntax lets you deconstruct a DTO directly in a case label, which reads almost like a spec:
return order switch
{
{ Total: > 1000 } => "high-value",
{ CustomerName.Length: 0 } => "anonymous",
_ => "standard"
};
Pattern matching against DTOs is a common pattern in notification hubs and event routers, where the shape of the message decides downstream behaviour. Records make that pattern terse and reliable, and they encourage code reviewers to read DTO branches as data rather than as control flow.
For serialisation, both System.Text.Json and Json.NET handle records without ceremony. Init-only properties are populated during deserialisation, and the default JSON converter respects value-based equality. A common pattern in Australian fintechs is to round-trip an OrderDto through a Service Bus queue and verify equality after deserialisation — a check that records make trivial.
Real-World Trade-Offs and Migration
Records are not a free upgrade. Their ToString() override dumps every member into the returned string, which can leak sensitive data into logs. Teams at organisations like Commonwealth Bank, Westpac, and several Melbourne-based health platforms often disable that override on DTOs that carry PII, replacing it with a redacting implementation or an explicit [DebuggerDisplay].
There is also the matter of inheritance. Records support record Derived : Base, but positional inheritance is restricted, and deep hierarchies can confuse serialisers. If your DTO graph is shallow — and most are — records are ideal. If it runs through four layers of abstraction, a regular class may be easier to reason about.
Finally, if you are still moving older code off the .NET Framework, you will eventually need a strategy for those legacy DTOs too. A useful walkthrough is the recent piece on migrating legacy .NET Framework apps to .NET Core on Azure, which covers how immutable payload contracts travel cleanly across the boundary once the runtime upgrade is in place.
When introducing records in a long-lived codebase, a staged rollout reduces friction. Start with new DTOs rather than migrations, train reviewers on the value-semantics model, and add an analyser rule to catch accidental setters on what should be immutable types.
A quick comparison across the three options follows, summarising the trade-offs in greenfield code under C# 12:
| Feature | Record class | Record struct | Class with primary constructor |
|---|---|---|---|
| Equality semantics | Value-based | Value-based | Reference-based by default |
| Memory location | Heap | Stack (usually) | Heap |
with expression |
Supported | Supported | Not supported |
| Inheritance model | Full record inheritance | Limited | Full class inheritance |
Default ToString |
Member-by-member | Member-by-member | Type name only |
| Best fit | API contracts | Small, hot-path payloads | Object graphs, migrations |
Rolling out records without friction
A short adoption checklist for teams in Australia's .NET community looks like this:
- Replace
classwithrecordon public DTO shapes first - Use
requiredon fields that the deserialiser must populate - Override
ToStringfor any DTO that may appear in logs - Avoid record structs larger than a handful of properties unless profiling demands them
Patterns that consistently show up in code reviews here:
- Positional records for inbound and outbound DTOs
withexpressions for creating modified copies without mutating the original- Switch expressions for routing decisions based on DTO shape
- Explicit
Equalsoverrides only when collections or computed fields need custom handling
Run that experiment on your own codebase before the next sprint planning session, and bring the line-count delta to the discussion. Your team will either cheer the cleanup or surface reasons to stay where you are, and either result is useful.
1, CBD, Maharaj Surajmal Road, Near Yamuna Sports Complex, Delhi, 110032
GENERAL QUERIES
Manish Tewatia
manish@csharpcon.com
+91-9718-431-042
TICKET QUERIES
Atul Gupta
conference@csharpcon.com
+91-9910-125-804