Open list without adding

public class RegistrationManager { public List<object> RegisteredObjects; public bool TryRegisterObject(object o) { // ... // Add or not to Registered // ... } } 

I want RegisterObjects be accessible from outside the class, but also that the only way to populate the RegisterObjects list is through TryRegisterObject(object o) .

Is it possible?

+7
list c # readonlycollection
source share
5 answers

I would have hidden it under ReadonlyCollection . In this case, the client will not be able to add elements through casting in IList, for example. It depends on how safe you want to be (in the simplest scenario, exposing IEnumerable will be enough).

 public class RegistrationManager { private List<object> _registeredObjects; ReadOnlyCollection<object> _readOnlyRegisteredObjects; public RegistrationManager() { _registeredObjects=new List<object>(); _readOnlyRegisteredObjects=new ReadOnlyCollection<object>(_registeredObjects); } public IEnumerable<object> RegisteredObjects { get { return _readOnlyRegisteredObjects; } } public bool TryRegisterObject(object o) { // ... // Add or not to Registered // ... } } 
+3
source share

Hide it under IEnumerable. You will get a readonly collection that will exit the class and work with the list inside:

 public class RegistrationManager { public IEnumerable<object> RegisteredObjects { get { return _registeredObjects; } } private List<object> _registeredObjects; public bool TryRegisterObject(object o) { // ... // Add or not to Registered // ... } } 

More secure option with IReadOnlyColection:

 public class RegistrationManager { public IReadOnlyCollection<object> RegisteredObjects { get { return new ReadOnlyCollection<object>(_registeredObjects); } } private List<object> _registeredObjects; public bool TryRegisterObject(object o) { // ... // Add or not to Registered // ... } } 
+3
source share

Something like this (I think you should have read-only access, which means Add , RemoveAt , Clear , etc. are not allowed):

 public class RegistrationManager { // change RegisteredObjects to be private //TODO: do you really want List<object> instead of, say, List<RegisteredItem>? private List<object> RegisteredObjects = new List<object>(); // let RegisteredObjects be visible as read-only public IReadOnlyList<object> Items { get { return RegisteredObjects; } } // your TryRegisterObject public bool TryRegisterObject(object o) { // ... // Add or not to Registered // ... } } 

the disadvantage of the solution is that it is technically possible to discard, for example,

  RegistrationManager manager = ... // you can't do this // manager.Items.Add(new Object()); // <- compile time error // but can do this ((List<Object>) (manager.Items)).Add(new Object()); 
+2
source share

return it as IReadOnlyList

 public class RegistrationManager { private List<object> _registeredObjects; public IReadOnlyList<object> RegisteredObjects { get{ return _registeredObjects; } } public bool TryRegisterObject(object o) { // ... // Add or not to Registered // ... } } 
+1
source share

Yes, you can open a property of type IReadOnlyCollection (T) .

List (T) implements IReadonlyCollection (T)

 public class RegistrationManager { private List<object> _registeredObjects; public IReadOnlyCollection<object> RegisteredObjects { get { return _registeredObjects as IReadOnlyCollection<object>; } } } 
0
source share

All Articles