C# supports two basic types : Value Type and Reference Type. The main difference between them where they get created: Value Types gets created in stack while Reference type in Heap. Other key difference, for ValueType whenever a parameter is passed as an argument, a copy gets created and passed while for reference types, refernce of the same onstance gets passed. There is another type called – Nullable Type but actually it’s a wrapper over value type. I wrote a post on it, you can have a look here.
All the Value Types internally inherits System.ValueType. Struct is also a ValueType which inherits same.
It’s a good idea to make struct immutable, it means once it is initalized, it cannot be modified. System.DateTime is an immutable Value Type. It provides many static methods but it always returns a new instance.
To make a struct immutable, the simple way to make all the members readonly and initializ these values via parameterized constructor. It’s members should be exposed via getter fields.
Let’s see an example
public struct Person { public string FirstName { get; } public string LastName { get; } public int Age { get; } public Person(string firstName, string lastName, int age) { this.FirstName = firstName; this.LastName = lastName; this.Age = age; } }
Above struct is immutable as there is no way to modify the initialized variable.
Read-Only structs:
Prior to C# 7.2, to create an Immutable value type, we had to write the struct in a way so that it doesn’t allow an update as in above example. If few fields are left without marking readonly/const unknowingly then it wont work as expected. C# 7.2 allows us to add readonly modifier before struct which makes sure thatg all the members are read only. If any member doesn’t, it will throw an error. Above struct can be marked as read only as
public readonly struct Person { public string FirstName { get; } public string LastName { get; } public int Age { get; } public Person(string firstName, string lastName, int age) { this.FirstName = firstName; this.LastName = lastName; this.Age = age; } }
One important thing, the parameterized constructor should be used to create the instance always else in case of using parameterless constructor use, the member would be set to default value which cannot be ever changed and we probably won’t want this. We cannot make parameter less private for struct in C# and even if there is a way we can bypass that. We can have some validate method which should be fired before using that struct’s memebers. I wont discuss this in details here.
Read-only struct provides framework support to write readonly struct and help us to avoid any unintended modification. In my previous post, I discussed about In modifier, it also can be used while passing any immutable object. These changes like ref, out, in etc in .NET framework got developed to make low level programming simpler and faster. Few more changes, we will be discussing in coming posts.
Note: If you are not sure how to use X# 7.2 (7.x) in your project, you may have a look on one of my previos post here.
Hope you enjoyed the post.
Cheers
Brij