List<T> readonly with a private set
C#.NetGenericsC# 3.0C# 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
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.