Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make List's Add method protected, while exposing List with get property?

I have a class named WhatClass that has List field in it. I need to be able to read-only this field, so I used a get property to expose it to other objects.

public class WhatClass {     List<SomeOtherClass> _SomeOtherClassItems;      public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems; } } } 

However it turns out that any object can call

WhatClass.SomeOtherClassItems.Add(item); 

How can I prevent this?

like image 650
Nikola Malešević Avatar asked Jul 15 '10 22:07

Nikola Malešević


People also ask

What method is used to add items to a list object?

One of those methods is .append() , you can add items to the end of an existing list object. You can also use . append() in a for loop to populate lists programmatically.


2 Answers

As others have said, you are looking for the .AsReadOnly() extension method.

However, you should store a reference to the collection instead of creating it during each property access:

private readonly List<SomeOtherClass> _items;  public WhatClass() {     _items = new List<SomeOtherClass>();      this.Items = _items.AsReadOnly(); }  public ReadOnlyCollection<SomeOtherClass> Items { get; private set; } 

This is to ensure that x.Items == x.Items holds true, which could otherwise be very unexpected for API consumers.

Exposing ReadOnlyCollection<> communicates your intent of a read-only collection to consumers. Changes to _items will be reflected in Items.

like image 176
Bryan Watts Avatar answered Sep 21 '22 21:09

Bryan Watts


You're looking for the ReadOnlyCollection<T> class, which is a read-only wrapper around an IList<T>.

Since the ReadOnlyCollection<T> will reflect changes in the underlying list, you don't need to create a new instance every time.

For example:

public class WhatClass {     public WhatClass() {         _SomeOtherClassItems = new List<SomeOtherClass>();         SomeOtherClassItems = _SomeOtherClassItems.AsReadOnly();     }      List<SomeOtherClass> _SomeOtherClassItems;      public ReadOnlyCollection<SomeOtherClass> SomeOtherClassItems { get; private set; } } 
like image 37
SLaks Avatar answered Sep 24 '22 21:09

SLaks