Eric Anastas
Eric Anastas

Reputation: 22213

How to return a readonly copy of a collection

I have a class that contains a collection. I want to provided a method or property that returns the contents of the collection. It's ok if calling classes can modify the individual objects but I do not want them adding or removing object from the actual collection. I have been copying all the objects to a new list, but now I'm thinking that I could just return the list as IEnumerable<>.

In the simplified example below is GetListC the best way to return a read only version of a collection?

public class MyClass
{
    private List<string> mylist;

    public MyClass()
    {
        mylist = new List<string>();
    }

    public void Add(string toAdd)
    {
        mylist.Add(toAdd);
    }

    //Returns the list directly 
    public List<String> GetListA 
    { 
        get
            {
            return mylist;
            }
    }

    //returns a copy of the list
    public List<String> GetListB
    {
        get
        {
            List<string> returnList = new List<string>();

            foreach (string st in this.mylist)
            {
                returnList.Add(st);
            }
            return returnList;
        }
    }

    //Returns the list as IEnumerable
    public IEnumerable<string> GetListC
    {
        get 
        {
            return this.mylist.AsEnumerable<String>();
        }

    }

}

Upvotes: 13

Views: 6970

Answers (4)

Robert
Robert

Reputation: 3062

I prefer returning IEnumerable, but you don't need to cast. Just do

public IEnumerable<string> StringList { get { return myList; }

List<string> is an IEnumerable<string>

Upvotes: -2

Joey
Joey

Reputation: 354436

You can use List(T).AsReadOnly():

return this.mylist.AsReadOnly()

which will return a ReadOnlyCollection.

Upvotes: 27

Dario
Dario

Reputation: 49208

Use the generic ReadOnlyCollection class (Collection.AsReadOnly()). It doesn't copy any objects which may have some strange results when the underlying collection is changed.

        var foo = new List<int> { 3, 1, 2 };
        var bar = foo.AsReadOnly();

        foreach (var x in bar) Console.WriteLine(x);

        foo.Sort();

        foreach (var x in bar) Console.WriteLine(x);

But if you don't want a copy, that's the best solution.

Upvotes: 0

nightcoder
nightcoder

Reputation: 13509

Just use ReadOnlyCollection class, it is supported since .NET 2.0

Upvotes: 2

Related Questions