An object is immutable if its state cannot change after construction. Immutable objects don't expose any way for other objects to modify their state; the object's fields are initialized only once inside the constructor and never change again.
Immutable classes make sure that values are not changed in the middle of an operation without using synchronized blocks. By avoiding synchronization blocks, you avoid deadlocks. And since you are always working with an unchangeable consistent state, you avoid race conditions.
If you want to encapsulate a mutable object into an immutable one, then you need to: Create a copy of the mutable object (i.e. via copy constructor, cloning, serialization/deserialization, etc.); never store the reference to the original mutable object. Never return the mutable object.
I think you're on the right track -
To be immutable, all your properties and fields should be readonly. And the items in any list should themselves be immutable.
You can make a readonly list property as follows:
public class MyClass
{
public MyClass(..., IList<MyType> items)
{
...
_myReadOnlyList = new List<MyType>(items).AsReadOnly();
}
public IList<MyType> MyReadOnlyList
{
get { return _myReadOnlyList; }
}
private IList<MyType> _myReadOnlyList
}
Also, keep in mind that:
public readonly object[] MyObjects;
is not immutable even if it's marked with readonly keyword. You can still change individual array references/values by index accessor.
Use the ReadOnlyCollection
class. It's situated in the System.Collections.ObjectModel
namespace.
On anything that returns your list (or in the constructor), set the list as a read-only collection.
using System.Collections.ObjectModel;
...
public MyClass(..., List<ListItemType> theList, ...)
{
...
this.myListItemCollection= theList.AsReadOnly();
...
}
public ReadOnlyCollection<ListItemType> ListItems
{
get { return this.myListItemCollection; }
}
All you need is L... Ehm record
and C# 9.0 or newer.
public record Customer(string FirstName, string LastName, IEnumerable<string> Items);
//...
var person = new Customer("Test", "test", new List<string>() { "Test1", "Test2", "Test3" });
// you can't change anything within person variable
// person.FirstName = "NewName";
This gets translated into immutable class called Customer with three properties, FirstName
, LastName
and Items
.
If you need an immutable (a read-only) collection as a property of the class, it is better to expose it as IEnumerable<T>
or ReadOnlyCollection<T>
than something from System.Collections.Immutable
Another option would be to use a visitor pattern instead of exposing any internal collections at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With