Home All Groups Group Topic Archive Search About

Mutable Types and Read-Only Fields

Author
20 Apr 2006 4:58 PM
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

Author
20 Apr 2006 5:53 PM
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).
Author
20 Apr 2006 6:18 PM
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.



--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
Author
22 Apr 2006 3:04 PM
david
On 2006-04-20, Mythran <kip_potter@hotmail.comREMOVETRAIL> wrote:
Show quoteHide quote
> 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.

Show quoteHide quote
>
> 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
>