C# 9.0 Record Type is reference type, but it has value equality feature: two variables of a record type are equal if the types match and all property and field values match.
For other reference types, equality means identity. That is, two variables of a reference type are equal if they refer to the same object.
However, we should be aware that the value equality of record type only applies to properties of following types:
- value type, such as int, double, DateTime, etc..
- string: even though string is reference type, it performs like value type
- record type
If the property inside the record type is a reference type (other than string or record type), this property would only equal if they point to the same object; otherwise, not equal.
Example 1:
internal record Person(string FirstName, string LastName, string[] PhoneNumbers);var phoneNumbers = new string[2];Person person1 = new("Nancy", "Davolio", phoneNumbers);
Person person2 = new("Nancy", "Davolio", phoneNumbers);Console.WriteLine(person1 == person2); // output: Trueperson1.PhoneNumbers[0] = "555-5555";
person2.PhoneNumbers[0] = "666-6666";Console.WriteLine(person1 == person2); // output: True
Console.WriteLine(person1.PhoneNumbers[0]); // output: 666-6666
Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
In the above example, the person1 and person2 have the same PhoneNumbers string array (reference type) instance. Therefore, person1 equals to person2. When changing the phone number for both person1 and person2, since the PhoneNumbers property points to the same string array, the second assignment to perso2’s phone number would overwrite the person1’s phone number.
Example 2:
internal record Person(string FirstName, string LastName, string[] PhoneNumbers);Person person1 = new("Nancy", "Davolio", new string[2]);
Person person2 = new("Nancy", "Davolio", new string[2]);Console.WriteLine(person1 == person2); // output: Falseperson1.PhoneNumbers[0] = "555-5555";
person2.PhoneNumbers[0] = "666-6666";Console.WriteLine(person1 == person2); // output: False
Console.WriteLine(person1.PhoneNumbers[0]); // output: 555-5555
Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
In the above example, the person1 and person2 have different PhoneNumbers string array (reference type) instance. Therefore, person1 does not equal to person2 because the PhoneNumbers property refers to different string arrays in person1 and person2 records.
In conclusion, in order to the value equality to work as expected, avoid using the reference types (other than string and record type) inside the record type definition.
Happy coding!