Yan Cui
I help clients go faster for less using serverless technologies.
As you might know already, an object is immutable if its state doesn’t change once it has been created.
In C# the most used immutable type is string, this means every time you modify the value of a string variable you are actually creating a new string object and updating the reference of the variable to point to the new object.
Class vs Struct
When creating a new type, you have the choice of either a class or a struct. The general rule of thumb is to go with a class except for lightweight types smaller than 16 bytes in which case it is more efficient to use a struct. The reason a struct can be more efficient is because a struct is a value type and therefore goes straight onto the stack so we don’t have the overhead of having to hold the reference to the object itself (4 bytes in a 32bit system).
Mutable vs Immutable
In addition, you also have to consider whether your type should be mutable or immutable. In general, a struct should always be immutable because a struct usually represents some fundamental value – such as the number 5 – and whilst you can change a variable’s value you don’t logically change the value itself.
Also, data loss is far too easy with mutable structs, consider the following:
Foo foo = new Foo(); // a mutable struct foo.Bar = 27; Foo foo2 = foo; foo2.Bar = 55;
Now foo.Bar and foo2.Bar is different, which is often unexpected.
Here are some of the advantages of using an immutable value type:
- Easier validation – if you validate the parameters used to construct your object, your object will never be invalid as its state can never be changed.
- Thread safety – immutable types are inherently thread-safe because there is no chance for different threads to see inconsistent views of the same data if the data can never be changed.
- Better encapsulation – immutable types can be exported from your objects safely because the caller cannot modify the internal state of your objects.
- Better for hash-based collections – the value returned by Object.GetHashCode() must be an instance invariant, which is always true for immutable types.
Deserializing an Immutable Struct
To create an immutable struct, you usually have no setters on properties and in all likelihood the private variables that the getters return will be made readonly too to enforce the write-once rule. The lack of public setters on properties, however, represents a challenge when serializing/deserializing the immutable structs.
The easiest way to get around this in my experience is to simply implement the ISerializable interface and providing a constructor which takes a SerializationInfo and a StreamingContext object:
[Serializable] public struct MyStruct: ISerializable { private readonly int _x; private readonly int _y; // normal constructor public MyStruct(int x, int y) : this() { _x = x; _y = y; } // this constructor is used for deserialization public MyStruct(SerializationInfo info, StreamingContext text) : this() { _x = info.GetInt32("X"); _y = info.GetInt32("Y"); } public int X { get { return _x; } } public int Y { get { return _y; } } // this method is called during serialization [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("X", X); info.AddValue("Z", Y); } }
Reference:
StackOverflow thread on immutability of structs
Patrick Smacchia’s article on Immutable Types: understand their benefits and use them
Eric Lippert‘s series on immutability in C#:
Immutability in C# Part One: Kinds of Immutability
Immutability in C# Part Two: A Simple Immutable Stack
Immutability in C# Part Three: A Covariant Immutable Stack
Immutability in C# Part Four: An Immutable Queue
Immutability in C# Part Five: LOLZ!
Immutability in C# Part Six: A Simple Binary Tree
Immutability in C# Part Seven: More on Binary Trees
Immutability in C# Part Eight: Even More On Binary Trees
Immutability in C# Part Nine: Academic? Plus my AVL tree implementation
Immutability in C# Part Ten: A double-ended queue
Immutability in C# Part Eleven: A working double-ended queue
Luca Bolognese‘s series on implementing immutable value objects:
Creating an immutable value object in C# – Part I – Using a class
Creating an immutable value object in C# – Part II – Making the class better
Creating an immutable value object in C# – Part III – Using a struct
Creating an immutable value object in C# – Part IV – A class with a special value
Creating an immutable value object in C# – Part V – Using a library
Whenever you’re ready, here are 3 ways I can help you:
- Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game. This is your one-stop shop for quickly levelling up your serverless skills.
- I help clients launch product ideas, improve their development processes and upskill their teams. If you’d like to work together, then let’s get in touch.
- Join my community on Discord, ask questions, and join the discussion on all things AWS and Serverless.
Pingback: Anders Hejlsberg’s podcast session with .Net Rocks! | theburningmonk.com
found your site on del.icio.us today and really liked it.. i bookmarked it and will be back to check it out some more later
Thanks for your great post.
I also refer very helpful blog about.Struct in C#.Net
Visit this helpful blog
http://www.mindstick.com/blog/83/Struct%20in%20C%20Net#.Vgjxz5c0Xcc
http://www.codeproject.com/Articles/8612/Structs-in-C