Liste en lecture seule avec un ensemble privé

Comment puis-je exposer une List pour qu’elle soit en lecture seule, mais peut être définie en privé?

Cela ne fonctionne pas:

 public List myList {readonly get; private set; } 

Même si vous faites:

 public List myList {get; private set; } 

Vous pouvez toujours faire ceci:

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

Je suppose que vous pourriez avoir:

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

Je pense que vous mélangez des concepts.

 public List myList {get; private set;} 

est déjà “en lecture seule”. Autrement dit, en dehors de cette classe, rien ne peut définir myList sur une autre instance de List

Cependant, si vous voulez une liste en lecture seule comme dans “Je ne veux pas que les gens puissent modifier le contenu de la liste”, vous devez exposer une ReadOnlyCollection . Vous pouvez le faire via:

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

Notez que dans le premier extrait de code, les autres utilisateurs peuvent manipuler la liste, mais ne peuvent pas modifier la liste que vous avez. Dans le second extrait, les autres utilisateurs obtiendront une liste en lecture seule qu’ils ne peuvent pas modifier.

Si vous souhaitez que readonly collection utilise ReadOnlyCollection , pas List :

 public ReadOnlyCollection MyList { get; private set; } 

Je préfère utiliser IEnumerable

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

Retourne un ReadOnlyCollection, qui implémente IList <>

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

Il existe une collection appelée ReadOnlyCollection – est-ce ce que vous recherchez?

Vous pouvez utiliser la méthode AsReadOnly () de List pour renvoyer un wrapper en lecture seule.

 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 } } 

Voici un moyen

 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"); } } 

Dans le framework .NET 4.5, vous ne pouvez exposer que l’interface IReadOnlyList . Quelque chose comme:

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

ou si vous voulez empêcher le casting indésirable à IList

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

Pourquoi utilisez-vous une liste? On dirait que ce que vous voulez vraiment exposer est IEnumerable

 public IEnumerable myList { get; private set; } 

Désormais, les utilisateurs de la classe peuvent lire les éléments, mais pas la liste.

Vous pouvez également créer votre liste normale, mais l’exposer via une propriété de type IEnumerable

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

Un peu tard, mais néanmoins: je n’aime pas utiliser le wrapper ReadOnlyCollection car il expose toujours toutes les méthodes de modification de la collection, qui lancent toutes une NotSupportedException lors de l’access en exécution. En d’autres termes, il implémente l’interface IList , mais viole ensuite ce même contrat au moment de l’exécution.

Pour exprimer que IIndexable vraiment une liste immuable, j’ai généralement recours à une interface IIndexable personnalisée, qui ajoute Length et un indexeur à un IEnumerable (décrit dans cet article CodeProject ). C’est un emballage car il aurait dû être fait en premier lieu à mon humble avis.

Je n’ai pas encore vu cette option mentionnée:

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

Cela devrait vous permettre d’exposer une liste en lecture seule.