Is it correct that it is not possible to change the value of an immutable object?
I have two scenarios regarding readonly
that I want to understand:
In languages like C++ there are quite a few different uses of the keyword "const", it is partly easy for developers to pass constant parameters and also constant pointers of constant values.
That is not easy in C#. We need to build immutable class by definition, which means Once an instance is created, there is no way it can be changed programmatically.
Java has a little easier way than C# because of the keyword final and its usages.
Lets consider this example and see how immutable it is..
public sealed class ImmutableFoo
{
private ImmutableFoo()
{
}
public string SomeValue { get; private set; }
//more properties go here
public sealed class Builder
{
private readonly ImmutableFoo _instanceFoo = new ImmutableFoo();
public Builder SetSomeValue(string someValue)
{
_instanceFoo.SomeValue = someValue;
return this;
}
/// Set more properties go here
///
public ImmutableFoo Build()
{
return _instanceFoo;
}
}
}
You can use it like this
public class Program
{
public static void Main(string[] args)
{
ImmutableFoo foo = new ImmutableFoo.Builder()
.SetSomeValue("Assil is my name")
.Build();
Console.WriteLine(foo.SomeValue);
Console.WriteLine("Hit enter to terminate");
Console.ReadLine();
}
}
Marking a field as read-only only means that you cannot change the value of that field. It has no bearing on the internal state of the object there. In your examples, while you would not be able to assign a new metadata object to the _metadata field, nor a new ICollection to the _items field (outside of a constructor that is), you can change the internal values of the existing objects stored in those fields.
An immutable object is one that cannot be changed, once created. In C# strings are immutable. If you look at the string manipulation routines you can see that all of them return a new, modified, string and leaves the original string unchanged.
This facilitates the string handling considerably. When you have a reference to a string, you can be sure that noone else will unexpectedly change it under your feet.
readonly
is something else. It means that the reference cannot be changed, once set and that it can only be set during object construction. In your examples you can change the contents of _items
or the properties of _metadata
, but you cannot assign another ICollection<MyItem>
to the _items
member or another Metadata
instance to _metadata
.
readonly
is set on the reference to an object. Immutability is a property of the object itself. These can be freely combined. To make sure that a property is not changed in any way, it should be a readonly reference to an immutable object.
private readonly ICollection<MyItem> _items;
Does not prevent items from being added. This simply prevents _items
from being re-assigned. The same is true for _metadata
. Accessible members of _metadata
can be changed - _metadata
cannot be re-assigned.
The readonly keyword applies to a variable - this means you can't assign another value to it, but you can alter its internal state. That's why you can alter a collection's items but you can't assign a new collection to the variable.