Mutable Types and Read-Only Fields

M

Mythran

http://msdn2.microsoft.com/en-US/library/ms229057(VS.80).aspx

* Do not assign instances of mutable types to read-only fields.

I would have to disagree with this "Field Design" guidelines...to an extent.

Example:

public class SomeClass {
private NameValueCollection mCollection;
public SomeClass() { mCollection = new NameValueCollection(); }
public NameValueCollection Collection {
get { return mCollection; }
}
public int CollectionCount()
{
return mCollection.Count;
}
}

For the above (granted, there may be some errors as this is just off top of
my head), the CollectionCount method requires that the mCollection field be
set. I expose the collection to the callee using a read-only property. The
property returns the mutable type just as I want. In a scenerio for my
example, the callee is allowed to change the internal collection values
(add/remove items to a list). But, if the user was allowed to modify the
actual reference, they could set it to null which would cause other areas of
the class (the mCollection.Count) to throw NullReferenceException's.
Therefore, am I not correct that in this instance, the mutable type being
returned by a read-only field is an exception to the rule?

Thanks,
Mythran
 
W

wfairl

Why does it need to be read only? Why not just have a get accessor? I
don't think there's any reason to this rule other than the fact that
"readonly mutable type" is misleading. Yes you can't change the
reference but readonly also should imply that you can't change the
value (and thus change things like the return from GetHashCode(), etc).
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

For the above (granted, there may be some errors as this is just off top
of my head), the CollectionCount method requires that the mCollection
field be set. I expose the collection to the callee using a read-only
property.

You expose it using a get property, using this only assure that the
reference holded in the class will not change, on other words, if you are
holding a reference to instance A the callee can not make change it to
instance B. IT DOES NOT assure that the instance itself cannot change its
state. If you want this the referenced class hasve to be inmutable ( like
string).
The property returns the mutable type just as I want. In a scenerio for
my example, the callee is allowed to change the internal collection values
(add/remove items to a list). But, if the user was allowed to modify the
actual reference, they could set it to null which would cause other areas
of the class (the mCollection.Count) to throw NullReferenceException's.
Therefore, am I not correct that in this instance, the mutable type being
returned by a read-only field is an exception to the rule?

I will try to explain, but the language can be confused, feel free to
comment back if further clarification is needed.

A readonly field and a read-only property ( which only define a get ) has
nothing in common. They are two completely different concepts.

a readonly field is declared using the readonly reserved word, this has two
implications:
1- a value should be assign in the spot or in a constructor
2- after it's assigned you cannot change it.

If you assign a primitive type you have effectively blocked that value :

readonly int i=5;

has the effect that i will ALWAYS be 5.

A similar thing happens with a struct:

public struct S
{
public int i;
}

class C
{
readonly S s = new S();

void method1()
{
s.i=4; //error
}

}


Now if the readonly is a referenced type, all the above change.

What you cannot change is the referenced instance, the member of the
instance can be changed at will:

public class S
{
public int i;
}

class C
{
readonly S s = new S();

void method1()
{
s.i=4; //good now
s = new S(); //error
}

}


hope this clarify it.
Let me know if not.
 
D

david

http://msdn2.microsoft.com/en-US/library/ms229057(VS.80).aspx

* Do not assign instances of mutable types to read-only fields.

I would have to disagree with this "Field Design" guidelines...to an extent.

Example:

public class SomeClass {
private NameValueCollection mCollection;
public SomeClass() { mCollection = new NameValueCollection(); }
public NameValueCollection Collection {
get { return mCollection; }
}
public int CollectionCount()
{
return mCollection.Count;
}
}

The guidelines you reference are distinguishing between fields and
properties. In the above code, the property is readonly, while the
field is not, which is exactly what the guidelines suggest doing.
 

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

Top