List<T> readonly with a private set

C#.NetGenericsC# 3.0

C# Problem Overview


How can I expose a List<T> so that it is readonly, but can be set privately?

This doesn't work:

public List<string> myList {readonly get; private set; }

Even if you do:

public List<string> myList {get; private set; }

You can still do this:

myList.Add("TEST"); //This should not be allowed

I guess you could have:

public List<string> myList {get{ return otherList;}}
private List<string> otherList {get;set;}

C# Solutions


Solution 1 - C#

I think you are mixing concepts.

public List<string> myList {get; private set;}

is already "read-only". That is, outside this class, nothing can set myList to a different instance of List<string>

However, if you want a readonly list as in "I don't want people to be able to modify the list contents", then you need to expose a ReadOnlyCollection<string>. You can do this via:

private List<string> actualList = new List<string>();
public ReadOnlyCollection<string> myList
{
  get{ return actualList.AsReadOnly();}
}

Note that in the first code snippet, others can manipulate the List, but can not change what list you have. In the second snippet, others will get a read-only list that they can not modify.

Solution 2 - C#

If you want readonly collection use ReadOnlyCollection<T>, not List<T>:

public ReadOnlyCollection<string> MyList { get; private set; }

Solution 3 - C#

I prefer to use IEnumerable

private readonly List<string> _list = new List<string>();

public IEnumerable<string> Values // Adding is not allowed - only iteration
{
   get { return _list; }
}

Solution 4 - C#

Return a ReadOnlyCollection, which implements IList<>

private List<string> myList;

public IList<string> MyList
{
  get{return myList.AsReadOnly();}
}

Solution 5 - C#

There's a collection called ReadOnlyCollection<T> - is that what you're looking for?

Solution 6 - C#

You can use List's AsReadOnly() method to return a read-only wrapper.

Solution 7 - C#

private List<string> my_list;

public ReadOnlyCollection<string> myList
{
    get { return my_list.AsReadOnly(); }
    private set { my_list = value; }
}

Solution 8 - C#

    private List<string> _items = new List<string>();         

    public ReadOnlyCollection<string> Items

    {

        get { return _items.AsReadOnly(); }

        private set { _items = value }

    }

Solution 9 - C#

Here is one way

public class MyClass
    {
        private List<string> _myList;
        public ReadOnlyCollection<string> PublicReadOnlyList { get { return _myList.AsReadOnly(); } }

        public MyClass()
        {
            _myList = new List<string>();
            _myList.Add("tesT");
            _myList.Add("tesT1");
            _myList.Add("tesT2");

            //(_myList.AsReadOnly() as List<string>).Add("test 5");
        }

    }

Solution 10 - C#

In the .NET 4.5 framework you can expose only the [IReadOnlyList][1] interface. Something like:

private List<string> _mylist;
public IReadOnlyList<string> myList { get {return _myList;} }

or if you want to prevent unwanted casting to IList

private List<string> _mylist;
public IReadOnlyList<string> myList { get {return new List<string>(_myList);} }

[1]: http://msdn.microsoft.com/en-us/library/hh192385.aspx "MSDN"

Solution 11 - C#

private List<string> myList;

public string this[int i]
{
    get { return myList[i]; }
    set { myList[i] = value; }
}

Solution 12 - C#

Why are you using a List. Sounds like what you really want to expose is IEnumerable

public IEnumerable<string> myList { get; private set; }

Now users of the class can read the items but not chagnge the list.

Solution 13 - C#

You could also create your normal list, but expose it through a property of type IEnumerable

private List<int> _list = new List<int>();

public IEnumerable<int> publicCollection{
   get { return _list; }
}

Solution 14 - C#

A bit late, but nevertheless: I don't like using the ReadOnlyCollection wrapper because it still exposes all the methods for modifying the collection, which all throw a NotSupportedException when accessed in run-time. In other words, it implements the IList interface, but then violates this same contract in run-time.

To express that I am really exposing an immutable list, I usually resort to a custom IIndexable interface, which adds Length and an indexer to an IEnumerable (described in this CodeProject article). It is a wrapper as it should have been done in the first place IMHO.

Solution 15 - C#

I didn't see this option mentioned yet:

private List<string> myList;

public List<string> MyList
{
    get { return myList.AsReadOnly().ToList(); }
}

This should allow you to expose a read-only List.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJonView Question on Stackoverflow
Solution 1 - C#Philip RieckView Answer on Stackoverflow
Solution 2 - C#Darin DimitrovView Answer on Stackoverflow
Solution 3 - C#Sergey BerezovskiyView Answer on Stackoverflow
Solution 4 - C#SeanView Answer on Stackoverflow
Solution 5 - C#Joe EnosView Answer on Stackoverflow
Solution 6 - C#Etienne de MartelView Answer on Stackoverflow
Solution 7 - C#TesserexView Answer on Stackoverflow
Solution 8 - C#zavazView Answer on Stackoverflow
Solution 9 - C#Dustin DavisView Answer on Stackoverflow
Solution 10 - C#Bohumil JandaView Answer on Stackoverflow
Solution 11 - C#Jonathan WoodView Answer on Stackoverflow
Solution 12 - C#tsterView Answer on Stackoverflow
Solution 13 - C#Adam RackisView Answer on Stackoverflow
Solution 14 - C#GrooView Answer on Stackoverflow
Solution 15 - C#Tim LehnerView Answer on Stackoverflow