Comment puis-je exposer un List<T>
pour qu'il soit en lecture seule, mais peut-il être défini en privé?
Cela ne fonctionne pas:
public List<string> myList {readonly get; private set; }
Même si vous le faites:
public List<string> 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<string> myList {get{ return otherList;}}
private List<string> otherList {get;set;}
Je pense que vous mélangez des concepts.
public List<string> 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<string>
Cependant, si vous voulez une liste en lecture seule comme dans "Je ne veux pas que les gens puissent modifier la liste contents", alors vous devez exposer un ReadOnlyCollection<string>
. Vous pouvez le faire via:
private List<string> actualList = new List<string>();
public ReadOnlyCollection<string> myList
{
get{ return actualList.AsReadOnly();}
}
Notez que dans le premier extrait de code, d'autres peuvent manipuler la liste, mais ne peuvent pas modifier la liste que vous avez. Dans le deuxième extrait, les autres obtiendront une liste en lecture seule qu'ils ne peuvent pas modifier.
Je préfère utiliser IEnumerable
private readonly List<string> _list = new List<string>();
public IEnumerable<string> Values // Adding is not allowed - only iteration
{
get { return _list; }
}
Si vous voulez une collection en lecture seule, utilisez ReadOnlyCollection<T>
, pas List<T>
:
public ReadOnlyCollection<string> MyList { get; private set; }
Renvoie un ReadOnlyCollection, qui implémente IList <>
private List<string> myList;
public IList<string> MyList
{
get{return myList.AsReadOnly();}
}
Il y a une collection appelée ReadOnlyCollection<T>
- c'est ce que vous cherchez?
Vous pouvez utiliser la méthode AsReadOnly () de List pour renvoyer un wrapper en lecture seule.
private List<string> my_list;
public ReadOnlyCollection<string> myList
{
get { return my_list.AsReadOnly(); }
private set { my_list = value; }
}
private List<string> _items = new List<string>();
public ReadOnlyCollection<string> Items
{
get { return _items.AsReadOnly(); }
private set { _items = value }
}
Voici une façon
public class MyClass
{
private List<string> _myList;
public ReadOnlyCollection<string> PublicReadOnlyList { get { return _myList.AsReadOnly(); } }
public MyClass()
{
_myList = new List<string>();
_myList.Add("tesT");
_myList.Add("tesT1");
_myList.Add("tesT2");
//(_myList.AsReadOnly() as List<string>).Add("test 5");
}
}
Dans le framework .NET 4.5, vous ne pouvez exposer que l'interface IReadOnlyList . Quelque chose comme:
private List<string> _mylist;
public IReadOnlyList<string> myList { get {return _myList;} }
ou si vous souhaitez empêcher la diffusion indésirable sur IList
private List<string> _mylist;
public IReadOnlyList<string> myList { get {return new List<string>(_myList);} }
private List<string> myList;
public string 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<string> myList { get; private set; }
Désormais, les utilisateurs de la classe peuvent lire les éléments mais pas modifier la liste.
Un peu en retard, 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 un NotSupportedException
lorsqu'elles sont accédées au moment de l'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 j'expose vraiment une liste immuable, j'ai généralement recours à une interface personnalisée IIndexable
, qui ajoute Longueur et un indexeur à un IEnumerable
(décrit dans cet article CodeProject ). Il s'agit d'un emballage comme cela aurait dû être fait en premier lieu à mon humble avis.