Friday, November 13, 2020

Finally, C# 9 record, the equivalent of Scala's case class

While C# is a wonderful programming language, there is something that I would like to see to make our life programmer easier. If you are familiar with the Scala programming language you would know about "case class". 

Object Comparison

The case class in Scala is designed to support immutable data modeling. It provides object comparison out of the box without you need to compare each property in the object. For example in C# you have a Person class as below:

class Person {

   public string FirstName {get; set;}

   public string LastName {get; set}

}

var a = new Person{ FirstName = "Michael", LastName = "Page" };

var b = new Person{ FirstName = "Michael", LastName = "Page" };

var sameObject = a.FirstName == b.FirstName && a.LastName == b.LastName; // true


While using the case class from Scala, you can do that easier as below:

case class Person(firstName: String, lastName: String)

val a = Person("Michael", "Page")

val b = Person("Michael", "Page")

val sameObject = a == b // true


Imagine if you have a huge object with a lot of properties and nested properties, doing object comparison in C# would be a non-trivial task. 

Object Copying

Working with an immutable object means we are not allowed to modify the existing object and we can only create new objects each time. Sometimes, what we want to do is just to modify some specific properties of the object and leave the other properties the same.

In C#, there was no such feature, creating a new object out of an existing object and change only one property is tiring as below (let's use the same person class):

var a = new Person{ FirstName = "Michael", LastName = "Page" };

var b = new Person{ FirstName = a.FirstName, LastName = "New last name" };

You can see, we need to map the other property (FirstName) to the new object as well and put the new value for the LastName. In Scala's case class, we can use the copy method:

val a = Person("Michael", "Page")

val b = a.copy(lastName = "New last name")

the new object "b" would have the same exact properties as the original object "a" and only changed the lastName. If there are many properties this is a huge time-saving.

C# 9 Record

In C# 9, now the gap is over. You can do what case class can do with C# too! 

public record Person {

   public string FirstName {get; init;}

   public string LastName {get; init;}

}

var a = new Person{ FirstName = "Michael", LastName = "Page" };

var b = new Person{ FirstName = "Michael", LastName = "Page" };

var sameObject = a == b; // true

This is how you declare a record of a person. And I have shown you that it supports object comparison out of the box, just like Scala's case class!

There is simpler syntax as well to declare the same record as below:

public record Person(string FirstName, string LastName);

var a = new Person("Michael", "Page");

var b = a with {LastName = "Lambda"}; // you just copied an object and with new LastName!!

var sameObject = a == b; // false

var (firstName, lastName) = b; // deconstructor => firstName = "Michael", lastName = "Lambda"

Not only that, it comes with copy feature using the "with" keyword. Also it provides positional deconstructor. I couldn't more happy now using C# 9.


Source:

https://devblogs.microsoft.com/dotnet/c-9-0-on-the-record/

https://docs.scala-lang.org/tour/case-classes.html

No comments:

Post a Comment

Finally, C# 9 record, the equivalent of Scala's case class

While C# is a wonderful programming language, there is something that I would like to see to make our life programmer easier. If you are fam...