Listar solo con un conjunto privado

¿Cómo puedo exponer una List para que sea de solo lectura, pero se puede establecer de forma privada?

Esto no funciona:

 public List myList {readonly get; private set; } 

Incluso si lo haces:

 public List myList {get; private set; } 

Todavía puedes hacer esto:

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

Supongo que podrías tener:

 public List myList {get{ return otherList;}} private List otherList {get;set;} 

Creo que estás mezclando conceptos.

 public List myList {get; private set;} 

ya es “de solo lectura”. Es decir, fuera de esta clase, nada puede establecer myList en una instancia diferente de List

Sin embargo, si desea una lista de solo lectura como en “No deseo que las personas puedan modificar los contenidos de la lista”, entonces debe exponer una ReadOnlyCollection . Puedes hacer esto a través de:

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

Tenga en cuenta que en el primer fragmento de código, otros pueden manipular la Lista, pero no pueden cambiar la lista que tiene. En el segundo fragmento, otros obtendrán una lista de solo lectura que no pueden modificar.

Si quiere una colección de solo lectura use ReadOnlyCollection , no List :

 public ReadOnlyCollection MyList { get; private set; } 

Prefiero usar IEnumerable

 private readonly List _list = new List(); public IEnumerable Values // Adding is not allowed - only iteration { get { return _list; } } 

Devuelve un ReadOnlyCollection, que implementa IList <>

 private List myList; public IList MyList { get{return myList.AsReadOnly();} } 

Hay una colección llamada ReadOnlyCollection . ¿Es eso lo que estás buscando?

Puede usar el método AsReadOnly () de List para devolver un contenedor de solo lectura.

 private List my_list; public ReadOnlyCollection myList { get { return my_list.AsReadOnly(); } private set { my_list = value; } } 
  private List _items = new List(); public ReadOnlyCollection Items { get { return _items.AsReadOnly(); } private set { _items = value } } 

Aquí hay una manera

 public class MyClass { private List _myList; public ReadOnlyCollection PublicReadOnlyList { get { return _myList.AsReadOnly(); } } public MyClass() { _myList = new List(); _myList.Add("tesT"); _myList.Add("tesT1"); _myList.Add("tesT2"); //(_myList.AsReadOnly() as List).Add("test 5"); } } 

En el marco .NET 4.5, puede exponer solo la interfaz IReadOnlyList . Algo como:

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

o si quieres evitar el lanzamiento indeseado a IList

 private List _mylist; public IReadOnlyList myList { get {return new List(_myList);} } 
 private List myList; public string this[int i] { get { return myList[i]; } set { myList[i] = value; } } 

¿Por qué estás usando una lista? Parece que lo que realmente quieres exponer es IEnumerable

 public IEnumerable myList { get; private set; } 

Ahora los usuarios de la clase pueden leer los elementos pero no cambiar la lista.

También podría crear su lista normal, pero exponerla a través de una propiedad de tipo IEnumerable

 private List _list = new List(); public IEnumerable publicCollection{ get { return _list; } } 

Un poco tarde, pero sin embargo: no me gusta usar el contenedor ReadOnlyCollection porque todavía expone todos los métodos para modificar la colección, que arrojan una NotSupportedException cuando se accede en tiempo de ejecución. En otras palabras, implementa la interfaz IList , pero luego viola este mismo contrato en tiempo de ejecución.

Para express que realmente estoy exponiendo una lista inmutable, por lo general IIndexable a una interfaz IIndexable personalizada, que agrega Length y un indexador a un IEnumerable (descrito en este artículo de CodeProject ). Es un contenedor como debería haberse hecho en primer lugar en mi humilde opinión.

No vi esta opción mencionada aún:

 private List myList; public List MyList { get { return myList.AsReadOnly().ToList(); } } 

Esto debería permitirle exponer una Lista de solo lectura.