immutable

  • Thread starter Thread starter fallenidol
  • Start date Start date
F

fallenidol

how do you create an immutable object in c#?

thanks in advance
 
An class whose data is provided in the constructor and has only
read-only properties is immutable. For example:

class IdNamePair {
private int id;
private string name;

public IdNamePair(int id, string name) {
this.id = id;
this.name = name;
}

public int Id { get { return id; } }
public string Name { get { return name; } }
}

Is immutable because there is no way to change id or name once they've
been set on the constructor. You can and should also specify readonly
on the field declarations but I wanted to leave that out here to
reinforce that the read-only properties are what make this class
immutable.

HTH,

Sam
 
Hi,

There is nothing in the language that check if a class you intended to make
inmutable is in reality inmutable.

Currently inmutable is more like a concept, it's simply a class that its
state does not change after it was initialized.

It's up to you do enforce it. You can only have "get" properties and none
method can have a side effect ( change the internals members).

Cheers,
IGnacio
 
Hi,

An class whose data is provided in the constructor and has only
read-only properties is immutable. For example:

No really, if you have method that changes the instance members the class
is not inmutable.



You can and should also specify readonly
on the field declarations but I wanted to leave that out here to
reinforce that the read-only properties are what make this class
immutable.


As a matter of fact that maybe the only way to really be sure that the class
will be inmutable.
And even so there is no enforcement of that. The above works for valued
types. In the case of the references you can only assure that the reference
will not chage. There is no way to enforce that the referenced instance does
not change.
 
Hi,



No really, if you have method that changes the instance members the class
is not inmutable.

And where is there a method changing the immutable value in my
example? As I said, the important part is the value is set in the
constructor and only a read-only property is available to read the
value. Therefore nothing is provided to change the value, hence it's
immutable.

Sam
 
string s = "this is an immutable object, because String is immutable";
 
As a side issues, all methods and properties on the class need to be coded
to avoid changing the contents of the class and they need to return a new
instance of the class. This allows, in the case of System.String

string s = "This is an example "
string r = s.Trim().ToUpper()

"r" now contains "THIS IS AN EXAMPLE"
"s' now contains "This is an example "

The system.DateTime class is another example of this type of functionality.

Mike Ober.
 
ignacio machin said:
There is nothing in the language that check if a class you intended to make
inmutable is in reality inmutable.

Currently inmutable is more like a concept, it's simply a class that its
state does not change after it was initialized.

It's up to you do enforce it. You can only have "get" properties and none
method can have a side effect ( change the internals members).

One thing missed from all of the replies so far is the possibility of
the values in the class not changing, but referenced objects changing.
For instance, is the following class immutable?

class Test
{
IList list = new ArrayList();

public IList List { get { return list; } }
}

You can't change which list an instance refers to, but you can change
the contents of the list.

(Similarly, even if a property returns a value type, if that value type
contains a mutable reference type you could observe a change.)
 
mmm i cannot see anyway of changing 'list' in your example. its created as
an empty arraylist and then all you can do i get it.
 
Hi,

And once you "get it", you can add to it:

Test test = new Test();
IList list = test.List;
list.Add(new object());
int c = list.Count;

// c = 1

You might have thought that the "test" variable was immutable because it only
contains a single, read-only property; However, it exposes a mutable
reference, making test itself mutable:

// use test.List again
list = test.List;
list.Add(new object());
c = list.Count;

// c = 2

Because test.List returns the same, mutable reference each time, the Count
will continue to increase when objects are added to the test.List.

--
Dave Sexton

fallenidol said:
mmm i cannot see anyway of changing 'list' in your example. its created as
an empty arraylist and then all you can do i get it.
 
You can't change the object that 'list' points at, but you can change the
contents of the list...

Test t = new Test();
Console.WriteLine( t.List.Count ); // Zero
t.List.Add(0);
Console.WriteLine( t.List.Count ); // One


fallenidol said:
mmm i cannot see anyway of changing 'list' in your example. its created as
an empty arraylist and then all you can do i get it.
 
Anyway if you want to be sure the "primitves" values inside the class are
immutable, they should be declared as readonly, because a property with just
a get is not enough.

Reflection allows to change private member values even if the class doesn't
expose set properties.
 
Hi,

But to be fair, reflection isn't part of the generally acceptable language
constructs used when designing a type-safe application. If you're trying to
design your classes to prevent reflection from changing the values of private
fields, then immutability will probably be the least of your concerns.

For example, you might want to support internal, lazy initialization on a
class but then maintain immutability afterwards. In that case, you won't be
able to mark the fields as read-only. I would still consider the class to be
immutable regardless of the possibility that another class will use reflection
as a means for unsanctioned change, simply because reflection can be used to
cause all sorts of undesirable effects for which you can't prepare ahead of
time.
 
Hi,

Does your solution protect against direct accessing the memory?
I don't have the idea about that.

I assume we are here talking about normal developing situations and for that
the answer from Samuel is in my idea more than enough.

Cor
 
fallenidol said:
mmm i cannot see anyway of changing 'list' in your example. its created as
an empty arraylist and then all you can do i get it.

Test t = new Test();

IList list = t.List;
list.Add (new Object());

That hasn't changed which list the Test instance refers to, but it
changes the contents of the list - so if someone else is using that
Test instance, they can't rely on the contents not changing. That's
pretty much the same as saying it's not immutable.
 
Michael D. Ober said:
As a side issues, all methods and properties on the class need to be coded
to avoid changing the contents of the class and they need to return a new
instance of the class. This allows, in the case of System.String

string s = "This is an example "
string r = s.Trim().ToUpper()

"r" now contains "THIS IS AN EXAMPLE"
"s' now contains "This is an example "

The system.DateTime class is another example of this type of functionality.

Just to be picky, DateTime is a struct - which fortunately, MS
understood they should make immutable.
 
news.microsoft.com said:
Anyway if you want to be sure the "primitves" values inside the class are
immutable, they should be declared as readonly, because a property with just
a get is not enough.

Reflection allows to change private member values even if the class doesn't
expose set properties.

What makes you think that making the field readonly would help?

using System;
using System.Reflection;

class Test
{
readonly int x;

public Test (int y)
{
x = y;
}

public int X
{
get { return x; }
}
}

class Entry
{
static void Main()
{
Test t = new Test(10);
Console.WriteLine (t.X);
FieldInfo fi = typeof(Test).GetField("x",
BindingFlags.NonPublic |
BindingFlags.Instance);
fi.SetValue (t, 20);
Console.WriteLine (t.X);

}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top