web-dev-qa-db-fra.com

Liste <T> en lecture seule avec un ensemble privé

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;}
50
Jon

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.

94
Philip Rieck

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; }
}
11
Sergey Berezovskiy

Si vous voulez une collection en lecture seule, utilisez ReadOnlyCollection<T> , pas List<T>:

public ReadOnlyCollection<string> MyList { get; private set; }
11
Darin Dimitrov

Renvoie un ReadOnlyCollection, qui implémente IList <>

private List<string> myList;

public IList<string> MyList
{
  get{return myList.AsReadOnly();}
}
10
Sean

Il y a une collection appelée ReadOnlyCollection<T> - c'est ce que vous cherchez?

4
Joe Enos

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

4
Etienne de Martel
private List<string> my_list;

public ReadOnlyCollection<string> myList
{
    get { return my_list.AsReadOnly(); }
    private set { my_list = value; }
}
4
Tesserex
    private List<string> _items = new List<string>();         

    public ReadOnlyCollection<string> Items

    {

        get { return _items.AsReadOnly(); }

        private set { _items = value }

    }
3
zavaz

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

    }
3
Dustin Davis

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);} }
3
Bohumil Janda
private List<string> myList;

public string this[int i]
{
    get { return myList[i]; }
    set { myList[i] = value; }
}
2
Jonathan Wood

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.

1
tster

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.

0
Groo