Come restituire una copia di sola lettura di una collezione
-
21-08-2019 - |
Domanda
Ho una classe che contiene una raccolta. Voglio fornito un metodo o una proprietà che restituisce il contenuto della raccolta. E 'ok se le classi di chiamata possono modificare i singoli oggetti, ma io non voglio che aggiungere o rimuovere oggetti dalla collezione reale. Sono stato copiare tutti gli oggetti da un nuovo elenco, ma ora sto pensando che ho potuto solo tornare la lista come IEnumerable <>.
Nell'esempio semplificato di seguito è GetListC il modo migliore per restituire una versione di sola lettura di una collezione?
public class MyClass
{
private List<string> mylist;
public MyClass()
{
mylist = new List<string>();
}
public void Add(string toAdd)
{
mylist.Add(toAdd);
}
//Returns the list directly
public List<String> GetListA
{
get
{
return mylist;
}
}
//returns a copy of the list
public List<String> GetListB
{
get
{
List<string> returnList = new List<string>();
foreach (string st in this.mylist)
{
returnList.Add(st);
}
return returnList;
}
}
//Returns the list as IEnumerable
public IEnumerable<string> GetListC
{
get
{
return this.mylist.AsEnumerable<String>();
}
}
}
Soluzione
È possibile utilizzare List(T).AsReadOnly()
:
return this.mylist.AsReadOnly()
che restituirà un ReadOnlyCollection
.
Altri suggerimenti
Basta usare classe ReadOnlyCollection, è supportata dal .NET 2.0
Utilizzare la classe ReadOnlyCollection generico (Collection.AsReadOnly()
). Non copiare alcun oggetto che potrebbe avere alcuni strani risultati quando la raccolta sottostante viene modificato.
var foo = new List<int> { 3, 1, 2 };
var bar = foo.AsReadOnly();
foreach (var x in bar) Console.WriteLine(x);
foo.Sort();
foreach (var x in bar) Console.WriteLine(x);
Ma se non si desidera una copia, che è la soluzione migliore.
Io preferisco tornare IEnumerable, ma non hai bisogno di gettare. Basta fare
public IEnumerable<string> StringList { get { return myList; }
List<string>
è una IEnumerable<string>