Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List Property Setter

When implementing a setter for a List property (in C#) is it a bad thing to write is as:

    private List<string> _TheList = new List<string>();
    public List<string> TheList
    {
        get { return _TheList; }
        set { _TheList = value; }
    }

Should it not be written as:

    private List<string> _TheList = new List<string>();
    public List<string> TheList
    {
        get { return _TheList; }
        set { _TheList = new List<string>(value); }
    }

Up until today I have typically used the former, but I recently found some code that was using the latter and it seemed that this is probably the correct way to implement this.

Won't using the former cause the TheList property to be changed when changes are made to the external list that gets assigned to it. For example:

List<string> list = new List<string>();
list.Add("Hello");

var c = new someClass();
c.TheList = list;

Using the former won't the following code break the encapsulation of TheList:

list.Clear();

Now c.TheList is also empty, which may not be what we wanted. However, using the latter approach, c.TheList would not be cleared.

like image 796
mikesigs Avatar asked Dec 09 '10 16:12

mikesigs


2 Answers

Collection properties should be readonly.

Your property should expose a Collection<T>, not a List<T>.

EDIT: Explanations:

If other code copies a reference to the list (eg, var list = Thingy.TheList), it can get messed up if you set the property to a different list. (It will end up holding an orphan)
In general, there are very few reasons to allow people to make a property point to a different collection instance.

Using Collection<T> instead of List<T> allows you to intercept changes to the collection and add validation or maintain parent fields. (by inheriting Collection<T> and overriding InsertItem and other methods) You can even add such logic after shippinga library without breaking calling code.

like image 63
SLaks Avatar answered Oct 18 '22 18:10

SLaks


I believe since a list is a reference object, all you need to do is get the reference. So:

   private List<string> _TheList = new List<string>();
public List<string> TheList
{
    get { return _TheList; }
}

Once you have the reference, and make changes to the collection, you're changing _TheList

like image 25
Brosto Avatar answered Oct 18 '22 16:10

Brosto