How is it different from class ?
Like class, a record is also a reference type. But the difference lies in how the variables of record types are compared for equality.
Two variables of a class type ARE EQUAL only:
- IF type of those two variables have the same class type
- AND IF the two variables are pointing to the same object
On the other hand, two variables of the record type ARE EQUAL only:
- IF the two variables have the same record type definition
- AND IF the values are equal in both records
So equality operators check equality of address pointers for class instances while they check for equality of values.
How to define record ?
Records is just another way of creating a user-defined type.
You can define a record just same as you define a class or struct. The only difference is – instead of using class or struct keyword, you use the ‘record‘ keyword. A record type can be either defined as value type or as a reference type.
record classis used, then it is a reference type. The keyword
record structis used, then it is a value type.
- If neither class nor struct is specified, then it is a reference type as
classkeyword is optional.
A record can also be marked as
sealed. Abstract record cannot be instantiated, same as with abstract classes. Sealed record prevents the further inheritance from that type.
In order to understand the concept, let’s take a simple code example.
We are going to create a console application to demonstrate the concepts. Below is step by step description of what we are going to do:
- Let’s create two classes: an
EmployeeClasswhich is derived from the abstract
- Let’s create two records: a
Employeerecord which is derived from the abstract
- Compare two instances of
Employeerecord, populate both with same data and compare them
- Compare tow instances of
EmployeeClass, populate both with same data and then compare them too
- Print the
ToString()outcome and the comparison result for records and classes.
Below is the code snippet. You can also find the code in my GitHub repository.
When the above code is executed, it would show you the result as shown in below snapshot. What have we proved ?
- The class instances are not considered as equal even though data in the objects is same. This is because both of the variables were pointing to different objects.
- The record instances are considered equal. This is because records compare only data while checking for equality.
- Also, we have seen that
ToString()method of record prints the property names and values, even though we have not written any code in record. But in case of classes, the default
ToString()implementation just prints fully qualified class name.
How is Value-Based-Equality enforced ?
We have seen that
ToString method and
equality operator (==) does have different behavior for records. Why could that be ?
As shown in above snapshot, the record has many additional methods. The snapshot shows equality
operators are overloaded and
Equals() method also is also overridden. As per documentation, below methods are generated by compiler while compiling record types.
- An override of Object.Equals(Object)
- A virtual
Equalsmethod whose parameter is the record type
- An override of Object.GetHashCode()
- Methods for
- Record types implement System.IEquatable<T>
- An override of Object.ToString()
This article is just an introduction to the record types. This article should help you to get basic understanding about how records can be declared and how do they behave.
We also saw records can be value type or reference type and they can also be abstract. There are other features that record types support and you may want to have look at documentation to know it more.
I hope you find this information helpful. Let me know your thoughts.