C# 9 record is not sugar for simple property POCO
Tags: dotnet, csharp
Published: 2020-11-23 12:05:56

# C# 9 record is not sugar for simple property POCO

Today I upgrade project to .NET 5 and try to rewrite package using C#9 syntax. I found that the previous thought for record is just a simple property POCO’s sugar is wrong.

Here, `simple property POCO` is defined as `public class Type {public string ID{get;set}/*..*/}` simple class code.

1\. rocord is indeed a class after compiler, but it is not a simple property POCO class.
Look at the IL Spy decompilation code and find that the system has done a lot for it.
![](https://i.imgur.com/lONIcH9.png)

2\. Default property is `{get;init;}` not `{get;set;}`, this means setting moment is in `constructor`, and that represent record by default is `immutable` and `thread-safe`, because the same value is achieved.

So when you use the Dapper similar framework to query the POCO data and want to modify the attributes, it will report the `CS8852` Unable to modify error.
![](https://i.imgur.com/Q2XmFq5.png)

3\. Change of `Equals` default logic .
You can see [the example written by TimCorey](https://www.youtube.com/watch?v=9Byvwa9yF-I) , see the == difference between the default class and record, [online test link](https://dotnetfiddle.net/knmHMu)

```C#
public class Program
{
	public static void Main()
	{
		var record1Obj1 = new record1(FirstName: "Lin", LastName: "WeiHan");
		var record1Obj2 = new record1(FirstName: "Lin", LastName: "WeiHan");
		Console.WriteLine(record1Obj1 == record1Obj2);//true

		var class1Obj1 = new Class1() { FirstName = "Lin", LastName = "WeiHan" };
		var class2Obj2 = new Class1() { FirstName = "Lin", LastName = "WeiHan" };
		Console.WriteLine(class1Obj1 == class2Obj2);//false
	}
}

public record record1(string FirstName,string LastName);

public class Class1
{
	public string FirstName {get;init;}
	public string LastName{get;init;}
}

```

![](https://i.imgur.com/dUfbWbe.png)

Because the record override `==` with `Equals` that as long as the same record type, and `propertys value are same` the system will be identified as `true` , which is commonly known `structural equality` , can look IL Spy decompile the code

```C#
	public virtual bool Equals(record2? other)
	{
		return (object)other != null && EqualityContract == other!.EqualityContract && EqualityComparer<string>.Default.Equals(FirstName, other!.FirstName) && EqualityComparer<string>.Default.Equals(LastName, other!.LastName);
	}
```

It is different from the object class default to get `RuntimeHelpers.GetHashCode` Handle logic.

4\. GetHashCode did similar logic, therefore `propertys value are same,hashCode'll be same'` , [test link](https://dotnetfiddle.net/CvthR4)
![](https://i.imgur.com/UF5Nok2.png)
IL Spy decompile Code

```C#
	public override int GetHashCode()
	{
		return (EqualityComparer<Type>.Default.GetHashCode(EqualityContract) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(FirstName)) * -1521134295 + EqualityComparer<string>.Default.GetHashCode(LastName);
	}
```

5\. Note that you can't treat record as a must `immutable`, because the reason is like below code that is unlimited...

```C#
public record record2
{
	public string FirstName {get;set;}
	public string LastName{get;set;}
}
```

Allow `{get;init;}` to `{get;set;}` , will lose `immutable`  and `thread-safe` behavior.
![](https://i.imgur.com/rgzM0RP.png)

6\. Record will help generate a readable ToString implementation. The
following image shows the difference between the ToString generated by a general class and a record
![](https://i.imgur.com/lzaWdHY.png)

7\. Record helps to generate `extend IEquatable<Type>` and implement strong typing, `public virtual bool Equals(Record1? other)`
![](https://i.imgur.com/7sEf6st.png)
which means it can avoid the original `public override bool Equals(object? obj)` need `unboxing and boxing performane` problems
![](https://i.imgur.com/A1FAPXP.png)

Read information:
*   [https://docs.microsoft.com/en\-us/dotnet/csharp/whats\-new/csharp\-9](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-9)
*   [https://www.youtube.com/watch?v=9Byvwa9yF\-I](https://www.youtube.com/watch?v=9Byvwa9yF-I)