37

I have some class with List-property:

class Foo {
  private List<int> myList;
}

I want provide access to this field only for read.

I.e. I want property with access to Enumerable, Count, etc. and without access to Clear, Add, Remove, etc. How I can do it?

John Leidegren
  • 58,171
  • 19
  • 126
  • 149
AndreyAkinshin
  • 17,723
  • 28
  • 93
  • 152
  • I'm going to go a head and change the title of this question to read-only because read-only and immutability are two very different albeit related topics, I'd prefer it if we did not mix them. If you're looking for immutability check out http://stackoverflow.com/a/9009748/58961. – John Leidegren Mar 09 '13 at 17:04
  • Possible duplicate of [Read-only list or unmodifiable list in .NET 4.0](https://stackoverflow.com/questions/984042/read-only-list-or-unmodifiable-list-in-net-4-0) – StayOnTarget Sep 27 '18 at 12:08

5 Answers5

52

You can expose a List<T> as a ReadOnlyCollection<T> by using the AsReadOnly() method

C# 6.0 and later (using Expression Bodied Properties)

class Foo { 

  private List<int> myList;

  public ReadOnlyCollection<int> ReadOnlyList => myList.AsReadOnly();

}

C# 5.0 and earlier

class Foo {

  private List<int> myList;

  public ReadOnlyCollection<int> ReadOnlyList {
     get {
         return myList.AsReadOnly();
     }
  }
}
FearlessHyena
  • 2,736
  • 29
  • 37
38

If you want a read-only view of a list you could use ReadOnlyCollection<T>.

class Foo {
    private ReadOnlyCollection<int> myList;
}
Community
  • 1
  • 1
Darin Dimitrov
  • 994,864
  • 265
  • 3,241
  • 2,902
  • 5
    Or, more accurately, a private `List` variable and a public `ReadOnlyCollection` property with a `get {}` that returns the variable. – Victor Nicollet Jan 13 '11 at 12:34
  • 5
    @Victor: that would give calling code access to the mutable list by a simple cast. Probably not what the OP wants. The readonly property could `return new ReadOnlyCollection(myList);` though. – Fredrik Mörk Jan 13 '11 at 12:35
  • 10
    ReadOnlyCollection is not really immutable as it contains a pointer to the original list - if you add something to your list, the readOnly-instance can access this new item either... but, you are right, when it comes down to modifications-methods - these are missing! –  Jan 13 '11 at 12:36
  • @Andreas: the OP does not state that the list content must not change; the only requirement given is that the calling code must not be able to change it. – Fredrik Mörk Jan 13 '11 at 12:39
  • @Fredrik: this is what I meant (and expressed quite awkwardly, I admit) ;-) – Victor Nicollet Jan 13 '11 at 12:42
  • @Fredrik Mörk: my comment was just for mentioning a side-effect –  Jan 13 '11 at 13:35
  • 1
    @FredrikMörk: because the title says "immutable". Perhaps it should be changed to "readonly". – David Schmitt Sep 25 '12 at 07:45
9

i would go for

public sealed class Foo
{
    private readonly List<object> _items = new List<object>();

    public IEnumerable<object> Items
    {
        get
        {
            foreach (var item in this._items)
            {
                yield return item;
            }
        }
    }
}
8

There is now an Immutable Collections library that does exactly that. Which you can install via nuget.

The immutable collection classes are supported starting with the .NET Framework 4.5.

https://msdn.microsoft.com/en-us/library/dn385366%28v=vs.110%29.aspx

The System.Collections.Immutable namespace provides generic immutable collection types that you can use for these scenarios, including: ImmutableArray<T>, ImmutableDictionary<Tkey,TValue>, ImmutableSortedDictionary<T>, ImmutableHashSet<T>, ImmutableList<T>, ImmutableQueue<T>, ImmutableSortedSet<T>, ImmutableStack<T>

Example of Usage:

class Foo
{
    public ImmutableList<int> myList { get; private set; }

    public Foo(IEnumerable<int> list)
    {
        myList = list.ToImmutableList();
    }
}
K. R.
  • 1,112
  • 16
  • 18
  • ImmutableList DOES allow you to add new elements, it just creates another list object for that. `Note that these methods return a new object. When you add or remove items from an immutable list, a copy of the original list is made with the items added or removed, and the original list is unchanged.` This answer shouldn't be upvoted. – AymenDaoudi Oct 08 '21 at 17:52
3

If you declare a readonly list in your class, you'll still be able to add items to it.

If you don't want to add or change anything, you should be using ReadOnlyCollection<T> as Darin suggested.

If you want to add, remove items from the list but don't want to change the content, you can use a readonly List<T>.

Pabuc
  • 5,500
  • 7
  • 35
  • 52